| 1 | // Implementation of ISBN check-digit verification |
|---|
| 2 | // Based on ISBN Users' Manual (http://www.isbn.org/standards/home/isbn/international/html/usm4.htm) |
|---|
| 3 | // and the Wikipedia treatment of ISBN (http://en.wikipedia.org/wiki/International_Standard_Book_Number) |
|---|
| 4 | |
|---|
| 5 | // This does not validate multiple ISBNs in one field, |
|---|
| 6 | // but it will gracefully ignore all non-number detritus, |
|---|
| 7 | // such as hyphens, spaces, and comments. |
|---|
| 8 | |
|---|
| 9 | // Takes the first 10 valid digits and tries to read an ISBN 10, |
|---|
| 10 | // and takes the first 13 valid digits to try to read an ISBN 13 |
|---|
| 11 | // Returns an four-element array: |
|---|
| 12 | // [0] the validity as an ISBN 10 |
|---|
| 13 | // [1] detected ISBN 10 that checks |
|---|
| 14 | // [2] validity as an ISBN 13 |
|---|
| 15 | // [3] detected ISBN 13 that checks |
|---|
| 16 | // If there is no valid ISBN of a type detected, then elements 1 and/or 3 will |
|---|
| 17 | // be empty. There could conceivably be a valid ISBN-13 with an ISBN-10 |
|---|
| 18 | // substring; this should probably be interpreted as the latter, but it is a |
|---|
| 19 | // client UI issue. |
|---|
| 20 | ISBNCheck = function(isbn) { |
|---|
| 21 | // For ISBN 10, multiple by these coefficients, take the sum mod 11 |
|---|
| 22 | // and subtract from 11 |
|---|
| 23 | var isbn10 = [10, 9, 8, 7, 6, 5, 4, 3, 2]; |
|---|
| 24 | |
|---|
| 25 | // For ISBN 13, multiple by these coefficients, take the sum mod 10 |
|---|
| 26 | // and subtract from 10 |
|---|
| 27 | var isbn13 = [1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3]; |
|---|
| 28 | |
|---|
| 29 | // We make a single pass through the provided string, interpreting the |
|---|
| 30 | // first 10 valid characters as an ISBN-10, and the first 13 as an |
|---|
| 31 | // ISBN-13. We then return an array of booleans and valid detected |
|---|
| 32 | // ISBNs. |
|---|
| 33 | |
|---|
| 34 | var j = 0; |
|---|
| 35 | var sum10 = 0; |
|---|
| 36 | var num10 = ""; |
|---|
| 37 | var sum13 = 0; |
|---|
| 38 | var num13 = ""; |
|---|
| 39 | var chars = []; |
|---|
| 40 | |
|---|
| 41 | for (var i=0; i < isbn.length; i++) { |
|---|
| 42 | if (isbn.charAt(i) == " ") { |
|---|
| 43 | // Since the space character evaluates as a number, |
|---|
| 44 | // it is a special case. |
|---|
| 45 | } else if (j < 9 && ((isbn.charAt(i) - 0) == isbn.charAt(i))) { |
|---|
| 46 | sum10 += isbn.charAt(i) * isbn10[j]; |
|---|
| 47 | sum13 += isbn.charAt(i) * isbn13[j]; |
|---|
| 48 | num10 += isbn.charAt(i); |
|---|
| 49 | num13 += isbn.charAt(i); |
|---|
| 50 | j++; |
|---|
| 51 | } else if (j == 9 && |
|---|
| 52 | (isbn.charAt(i) == "X" || isbn.charAt(i) == "x" || |
|---|
| 53 | ((isbn.charAt(i) - 0) == isbn.charAt(i)))) { |
|---|
| 54 | // In ISBN-10, an X represents the check digit "10". |
|---|
| 55 | if(isbn.charAt(i) == "X" || isbn.charAt(i) == "x") { |
|---|
| 56 | var check10 = 10; |
|---|
| 57 | num10 += "X"; |
|---|
| 58 | } else { |
|---|
| 59 | var check10 = isbn.charAt(i); |
|---|
| 60 | sum13 += isbn.charAt(i) * isbn13[j]; |
|---|
| 61 | num10 += isbn.charAt(i); |
|---|
| 62 | num13 += isbn.charAt(i); |
|---|
| 63 | j++; |
|---|
| 64 | } |
|---|
| 65 | } else if(j < 12 && ((isbn.charAt(i) - 0) == isbn.charAt(i))) { |
|---|
| 66 | sum13 += isbn.charAt(i) * isbn13[j]; |
|---|
| 67 | num13 += isbn.charAt(i); |
|---|
| 68 | j++; |
|---|
| 69 | } else if (j == 12 && ((isbn.charAt(i) - 0) == isbn.charAt(i))) { |
|---|
| 70 | var check13 = isbn.charAt(i); |
|---|
| 71 | num13 += isbn.charAt(i); |
|---|
| 72 | } |
|---|
| 73 | } |
|---|
| 74 | var valid10 = (11 - (sum10 % 11) == check10); |
|---|
| 75 | var valid13 = (10 - (sum13 % 10) == check13); |
|---|
| 76 | if(!valid10) {num10 = ""}; |
|---|
| 77 | if(!valid13) {num13 = ""}; |
|---|
| 78 | return [valid10, num10, valid13, num13]; |
|---|
| 79 | } |
|---|