Skip to content

Extracting an ISBN From a Copyright Page and Validating It

9 min read · updated August 11, 2026

An ISBN is one of the small number of fields in document extraction that you can check without asking anybody. The last digit is computed from the other twelve, so a misread is arithmetically detectable on the page. The harder problem is that a copyright page normally prints four of them and only one is the edition you are holding.

There is more than one ISBN on the page

The International ISBN Agency assigns a separate ISBN to every separately available product form of a title. A trade publisher will therefore print, on one copyright page, an ISBN for the hardcover, one for the paperback, one for the ebook, and frequently distinct ones for the EPUB and PDF ebook formats, plus an audiobook. They are usually set as a short labelled list:

ISBN 978-0-306-40615-7 (hardcover)
ISBN 978-0-306-40616-4 (paperback)
ISBN 978-0-306-40617-1 (ebook)

An extractor whose schema has a single isbn string will return whichever one the model saw first, silently, and it will be right about two thirds of the time. The field is a list of pairs — number and product form — and the question “which ISBN is this copy?” is answered by the barcode on the back cover, not by the copyright page. If you have both images, the back-cover EAN-13 is the authority for the physical object in your hands, because it is the number the retailer scanned.

Product-form labels are not standardised in the way the number is. You will see (pbk.), (paperback), (alk. paper),(cloth), (hbk.), (e-book), (EPUB) and, on older books catalogued in the Library of Congress CIP block, descriptors that have nothing to do with binding at all. Normalise these to a small enum with an other bucket and keep the raw string next to it, because the raw string is the only way anyone will diagnose a bad mapping later.

The mod-10 check digit, worked

An ISBN-13 is thirteen digits. The first twelve carry the prefix element (978 or 979), the registration group, the registrant and the publication. The thirteenth is computed: multiply the digits alternately by 1 and 3 starting with 1 at the leftmost digit, sum, and the check digit is whatever makes the total a multiple of ten. This is the same modulo-10 scheme EAN-13 and GS1’s GTIN-13 use, which is why the barcode on the back of the book and the number on the copyright page share a final digit.

Take 978-0-306-40615-7, the example number the ISBN agency itself uses in its documentation. Strip the hyphens and weight the first twelve digits:

digit   9  7  8  0  3  0  6  4  0  6  1  5
weight  1  3  1  3  1  3  1  3  1  3  1  3
term    9 21  8  0  3  0  6 12  0 18  1 15

sum = 93
93 mod 10 = 3
check digit = (10 - 3) mod 10 = 7   ->  matches the printed 7

The mod 10 on the outside matters: when the sum is already a multiple of ten the check digit is 0, not 10. That single case is the most common bug in a hand-written ISBN validator, and it is why you should write the arithmetic rather than a regular expression. A regex confirms the shape and nothing else; the check digit confirms the content.

What this buys you in an extraction pipeline is a hard rejection signal that owes nothing to the model. If the OCR returns a thirteen-digit number whose check digit does not compute, one of the digits is wrong, and you know that before any human looks at the page. That is a different and much stronger position than a per-field confidence score, which tells you how sure the model was rather than whether the answer is possible. Both are worth having — see what a confidence score is measuring — but only one of them is arithmetic.

ISBN-10, mod 11, and the X

Books published before 2007, and a great many published since, print the ISBN-10 alongside the ISBN-13. It uses a different algorithm: weight the ten digits by 10, 9, 8 … 1 from the left, and the total must be divisible by eleven. Because the residue can be ten, the check character has eleven possible values, and the tenth is written as the letter X.

0-306-40615-2

digit   0  3  0  6  4  0  6  1  5   check
weight 10  9  8  7  6  5  4  3  2       1
term    0 27  0 42 24  0 24  3 10

sum of the first nine = 130
130 mod 11 = 9
check digit = 11 - 9 = 2   ->  matches the printed 2

Two consequences for extraction. First, a validator that only knows mod 10 will reject every ISBN-10 on the page, and a field typed as an integer will reject the X outright — keep it a string. Second, the ISBN-10 and ISBN-13 on a copyright page are normally the same publication: drop the ISBN-10’s check digit, prefix 978, and recompute, and you should land exactly on the printed ISBN-13. If you do not, one of the two was mis-OCRed and you can say which by testing both check digits independently.

That conversion does not run in reverse for the 979 prefix. There is no ISBN-10 corresponding to a 979-prefixed ISBN-13, so a page showing a 979 number and a ten-digit number is showing you two different things and you should not try to reconcile them.

The numbers next to it that are not ISBNs

The copyright page is dense with identifiers that a model will happily hand you when you asked for an ISBN.

  • The printing line. A descending or interleaved run such as 10 9 8 7 6 5 4 3 2 1. The lowest number present is the printing, so a line reading 10 9 8 7 6 5 4 is a fourth printing. It is genuinely useful metadata and it is not a number to checksum.
  • The LCCN. A Library of Congress Control Number, two or four year digits then a serial. No check digit.
  • A DOI on academic titles, beginning 10. and containing a slash.
  • An ISSN on anything published in a series: eight digits with its own mod-11 check character, also allowing X. Structurally similar enough to an ISBN-10 to be confused with one, and two digits shorter.
  • The publisher’s internal SKU, which looks like whatever the publisher wants.

The cheap discriminator is length after removing separators: thirteen digits beginning 978 or 979, ten characters, or eight. Apply the matching check digit and let the arithmetic reject the impostors.

Where the extraction actually breaks

Hyphenation is not fixed-width. The registration group and registrant elements are variable length, so 978-0-306-40615-7 and 978-93-5000-000-0 hyphenate differently and neither pattern generalises. Strip all hyphens and spaces before validating. If you need to re-hyphenate for display you need the agency’s published range table, not a rule of thumb.

The digits that OCR confuses are not random. On the small type of a copyright page the recurring substitutions are 8 for B, 0 for O or D, 1 for I or l, and 5 for S. All of those turn a valid ISBN into an invalid one that still looks like a number, which is exactly the case the check digit catches. What it does not catch is a transposition of two adjacent digits where one weight is 1 and the other is 3 and the swap happens to preserve the sum — mod-10 with alternating weights detects all single-digit errors but not every transposition, so a check-digit pass is a strong filter and not a proof.

Line wrapping splits the number. In a narrow copyright-page column the ISBN can break across two lines with the hyphen doing double duty as a line break. Join candidate lines before you parse, and treat a ten-or-eleven-digit fragment followed by a two-or-three-digit fragment as one candidate.

The CIP block repeats the number in a different form. A Cataloguing-in-Publication block reproduces the ISBNs inside a structured bibliographic record with its own punctuation. Extracting from both the CIP block and the surrounding page yields duplicates that differ only in whitespace, which is a deduplication problem rather than a reading problem — normalise to the unhyphenated form as the key.

None of this needs a vision model to be doing anything clever. It needs the page read once, every candidate string put through the two check-digit algorithms, and the survivors labelled with their product form. The same discipline applies to any identifier that carries its own check character, which is most of the ones printed on product and warranty certificates.

Prefix and range allocations are maintained by the International ISBN Agency and change as registration groups fill up; the check-digit algorithms do not. If you need the current ranges, take them from the International ISBN Agency rather than from a copy in your codebase.