isbn.zig #
A Zig library for parsing, validating, and converting International Standard Book Numbers (ISBNs) in both the 10-digit and 13-digit formats.
The API documentation is generated from the doc comments in the source
and published at https://jeff.jcollie.page/isbn.zig/. To read it
locally instead, zig build docs builds it into zig-out/docs and
zig build docs-serve serves it on http://127.0.0.1:8000/. A server
is needed rather than opening the files directly, because the viewer
fetches sources.tar and main.wasm at runtime and a browser refuses
those from a file:// page.
Features #
- Parse ISBNs from text, with or without
-separators. - Validate check digits during parsing (including the
Xcheck digit used by ISBN-10). - Compute check digits, optionally using SIMD vector operations.
- Upgrade an ISBN-10 to its equivalent ISBN-13.
- Compare ISBNs across formats: an ISBN-10 is equal to its 13-digit equivalent.
- Format ISBNs with proper hyphenation, using the International ISBN Agency's registration group and registrant range data.
Requirements #
- Zig 0.16.0 or later
Installation #
Add the dependency to your project:
zig fetch --save git+https://tangled.org/jcollie.dev/isbn.zig
Then wire it up in your build.zig:
const isbn = b.dependency("isbn", .{
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("isbn", isbn.module("isbn"));
Usage #
const ISBN = @import("isbn").ISBN;
// Parsing validates the check digit.
const ten: ISBN = try .parse("0-306-40615-2");
const thirteen: ISBN = try .parse("978-0-306-40615-7");
// Upgrade an ISBN-10 to an ISBN-13.
const upgraded = ten.upgrade();
// Comparison works across formats.
std.debug.assert(ten.eql(&thirteen));
// Hyphenate explicitly, or format with {f}.
var buf: [ISBN.max_hyphenated_len]u8 = undefined;
const hyphenated = try upgraded.hyphenate(&buf);
std.debug.print("{s}\n", .{hyphenated}); // 978-0-306-40615-7
std.debug.print("{f}\n", .{ten}); // 0-306-40615-2
parse returns error.ParseError for malformed input and
error.InvalidCheckDigit when the check digit doesn't match.
Build options #
-Dsimd=[bool]— use SIMD vector operations for computing check digits (default:false). It is off because it does not pay:zig build benchmeasures both implementations, and nine or twelve lanes of multiply-and-add do not earn back the cost of widening the digits and assembling the vector.-Ddocs-port=[u16]— port forzig build docs-serve(default:8000).
Standards #
| Standard | Title | Support in isbn.zig |
|---|---|---|
| ISO 2108 | International Standard Book Number | Parsing and validating both the 10- and 13-digit forms, the two check digit algorithms, and conversion from 10 to 13 |
| ISBN range message | Registration group and registrant ranges | Hyphenation, from the International ISBN Agency's published ranges, generated into src/ranges.zig |
| EAN/UPC (GS1) | Article numbering | The 978 and 979 prefixes an ISBN-13 is built on |
ISO 2108 itself is not freely available. The check digit algorithms and the 978/979 prefixes are documented in the ISBN Users' Manual, which is: https://www.isbn-international.org/content/isbn-users-manual
Range data #
Hyphenation uses the registration group and registrant ranges published
by the International ISBN Agency,
embedded at build time as src/ranges.zig. To update them:
zig build update-ranges
Testing #
zig build test
The test suite includes unit tests and a fuzz test.
zig build check compiles everything that zig build test does not
run — the benchmark, the documentation server, and the range generator
— so that none of them can quietly stop compiling.
zig build bench compares the SIMD and scalar check digit
implementations against each other; it calls both directly, so the
-Dsimd setting does not affect what it measures.
License #
MIT. This project is compliant with the REUSE Specification.