Skip to content

Instantly share code, notes, and snippets.

@Juul
Last active April 15, 2026 03:19
Show Gist options
  • Select an option

  • Save Juul/9b83007e5566ccbf84c29a015efbaf79 to your computer and use it in GitHub Desktop.

Select an option

Save Juul/9b83007e5566ccbf84c29a015efbaf79 to your computer and use it in GitHub Desktop.
Command-line node.js script to calculate an ISBN from an SBN
#!/usr/bin/env node
// Command-line node.js script to calculate an ISBN from an SBN
// Note that this re-calculates the check digit (the last digit)
// which may not be the correct thing to do.
// Wikipedia claims that it should _not_ be recalculated but cites no sources
//
// This script can also re-calculate a bad check digit in an SBN or ISBN
// using ./sbn_to_isbn -f <sbn_or_isbn>
var tryFix = false
function calculateCheckDigit(isbn) {
const str = isbn.toString();
var sum = 0;
var i, number;
for(i=0; i < str.length; i++) {
number = str[i].toLowerCase();
if(number == 'x') number = 10;
sum += (i+1) * parseInt(str[i]);
}
return sum % 11;
}
function fixCheckDigit(sbnOrIsbn, convertSbnToIsbn) {
// Remove old check digit
var digits = sbnOrIsbn.toString().slice(0,-1);
// Prepend 0 if we're converting
if(convertSbnToIsbn) {
digits = '0'+digits;
}
checkDigit = calculateCheckDigit(digits);
if(checkDigit == 10) {
digits += 'X';
} else {
digits += checkDigit;
}
return digits;
}
function sbnToIsbn(sbnOrIsbn) {
if(calculateCheckDigit(sbnOrIsbn.toString())) {
console.error("Invalid SBN!");
if(!tryFix) {
process.exit(1);
}
sbnOrIsbn = fixCheckDigit(sbnOrIsbn);
if(sbnOrIsbn.length > 9) {
console.log("Attempted fixed ISBN-10:", sbnOrIsbn);
process.exit(0);
} else {
console.log("Attempted fixed SBN:", sbnOrIsbn);
}
}
const isbn10 = fixCheckDigit(sbnOrIsbn, true);
console.log("ISBN-10:", isbn10);
}
if(process.argv.length < 3) {
console.log("Usage: ./sbn_to_isbn [-f] <sbn>");
console.log('');
console.log(" -f: Attempt to fix by re-calculating SBN check digit");
console.log('');
process.exit(1)
}
var sbnOrIsbn = process.argv[2];
if(process.argv.length > 3 && process.argv[2] == '-f') {
tryFix = true;
sbnOrIsbn = process.argv[3]
}
sbnToIsbn(sbnOrIsbn);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment