OSS4Lib and David Bigwood (Catalogablog) wrote the other day about an ISBN tool from ManaSystems that converts ISBN-10 to ISBN-13. ManaSystem’s version is written in Perl, so I went ahead and ported it to PHP5 for the rest of us.
Feel free to download it here, or from my files section.
Basically, all the function names are the same, so the original instructions apply. From the ISBN.pl page:
convert($isbn)
Takes a 10 digit ISBN and returns the 13 digit equivalent. Does not perform any error checking or validation.gettype($isbn)
Takes a string value and will make a guess as to whether or not it fits the criteria of an ISBN. Returns 10 for a possible ISBN-10 and 13 for ISBN-13. Does not validate further.validateten($isbn)
Takes a 10 digit numeric value and checks to determine if it is a valid ISBN-10.validatettn($isbn)
Takes a 13 digit digit numeric value and checks to determine if it is a valid ISBN-13.genchksum13($isbn)
Takes a 12 digit numeric value and generates an ISBN-13 checksum digit.genchksum10($isbn)
Takes a 9 digit numeric value and generates an ISBN-10 checksum digit.printinvalid() Returns a message informing the user the ISBN is invalid.
Of course, you’ll instantiate it a little differently:
require_once('ISBN.php'); $isbn_no = "012345678"; $ISBN = new ISBN; $isbntype = $ISBN->gettype($isbn_no); if ($isbntype < 1) { $ISBN->printinvalid(); } else if ($isbntype == 10) { $isvalidten = $ISBN->validateten($isbn_no); } else if ($isbntype == 13) { $isvalidttn = $ISBN->validatettn($isbn_no); } if ($isvalidten) { print "That is a valid ISBN-10\n"; } else if ($isvalidttn) { print "That is a valid ISBN-13\n"; } else { $ISBN->printinvalid(); }
Enjoy!














22 Comments so far
Leave a comment
Nice! Maybe you could post this to oss4lib.org?
Thanks, -dc
By dchud on 04.06.06 11:48 am | Permalink
Hi.. I modified this so that it runs on PHP4. also, your call to gettype never actually validates the numbers.
/* http://www.blyberg.net * @Desc ISBN Class, adapted from ISBN.pm - http://www.manasystems.co.uk/isbnpm.html */ function isbn_convert($isbn) { $isbn2 = substr("978" . trim($isbn), 0, -1); $sum13 = isbn_genchksum13($isbn2); $isbn13 = "$isbn2-$sum13"; return ($isbn13); } function isbn_gettype($isbn) { $isbn = trim($isbn); if (preg_match('%[0-9]{12}?[0-9Xx]%s', $isbn)) { if (isbn_validatettn($isbn)==1){ return 13; } else {return(-1);} } else if (preg_match('%[0-9]{9}?[0-9Xx]%s', $isbn)) { if (isbn_validateten($isbn)==1){ return 10; } else {return -1;} } else { return -1; } } function isbn_validateten($isbn) { $isbn = trim($isbn); $chksum = substr($isbn, -1, 1); $isbn = substr($isbn, 0, -1); if (preg_match('/X/i', $chksum)) { $chksum="10"; } $sum = isbn_genchksum10($isbn); if ($chksum == $sum){ return 1; }else{ return 0; } } function isbn_validatettn($isbn) { $isbn = trim($isbn); $chksum = substr($isbn, -1, 1); $isbn = substr($isbn, 0, -1); if (preg_match('/X/i', $chksum)) { $chksum="10"; } $sum = isbn_genchksum13($isbn); if ($chksum == $sum){ return 1; }else{ return 0; } } function isbn_genchksum13($isbn) { $isbn = trim($isbn); for ($i = 0; $iBy Michael Johnson on 04.20.06 10:18 am | Permalink
Fixed some buggyness in your checksum routines:
I seemed to get some ISBN 10’s that would calc incorrectly using your code (ex:0756612950)
function isbn_genchksum13($isbn) { $t = 2; $isbn = trim($isbn); $b=0; for($i = 1; $i <= 12; $i++){ $c = substr($isbn,($i-1),1); if ($i % 2==0){ $a = (3 * $c); } else { $a = (1 * $c); } $b=$b+$a; } $sum = 10 - ($b % 10); return $sum; } function isbn_genchksum10($isbn) { $t = 2; $isbn = trim($isbn); $b=0; for($i = 0; $i < 9; $i++){ $c = substr($isbn,$i,1); $a = (($i+1) * $c); $b=$b+$a; } $sum = ($b % 11); return $sum; }By Mike Johnson on 04.21.06 1:19 pm | Permalink
Mike,
Thanks for these fixes! I’ll get them packaged up when I have a moment or two…
By john on 04.21.06 1:42 pm | Permalink
Here’s a couple of additional simple functions to clean out spaces and dashes, and also one to convert from ISBN-13 back into ISBN-10, which is nice for searches etc. I’m using it with PHP4 but you can easily adapt it to PHP5 by changing the “$this->” string.
//Clean out the dashes and spaces from passed ISBN
function cleandashes($isbn){
return $isbn = str_replace(array('-', ' '), '', $isbn);
}
//Conver ISBN-13 back into ISBN-10
function convert13($isbn) {
$isbn2 = substr("" . trim($isbn), 3, 13);
$sum13 = $this->genchksum10($isbn2);
$isbn13 = $isbn2.$sum13;
return ($isbn13);
}
By Stijn on 07.05.06 10:48 am | Permalink
Had an error in my last post, ISBN-13 to ISBN-10 should work now.
//Convert ISBN-13 back into ISBN-10
function convert13($isbn) {
$isbn2 = substr("" . trim($isbn), 3, 9);
$sum10 = genchksum10($isbn2);
$isbn10 = $isbn2.$sum10;
return ($isbn10);
}
By Stijn on 07.05.06 11:20 am | Permalink
One last fix, checksums of 10 need to be converted to “X”. Don’t forget to test for lowercase “x” too.
//Conver ISBN-13 back into ISBN-10
function convert13($isbn) {
$isbn2 = substr(”" . trim($isbn), 3, 9);
$sum10 = $this->genchksum10($isbn2);
if ($sum10==10) {$sum10=’X';}
$isbn10 = $isbn2.$sum10;
return ($isbn10);
}
By Stijn on 07.05.06 12:22 pm | Permalink
[…] John Blyberg’s PHP port of the PERL ISBN-10/13 tool […]
By Converting Between ISBN-10 and ISBN-13 « MaisonBisson.com on 10.02.06 1:23 pm | Permalink
Mikes code almost works, it’s missing one vital part though.
add if($sum == 10) $sum = 0; before the return statement in genchksum13.
Like this:
public function genchksum13($isbn) {
$t = 2;
$isbn = trim($isbn);
$b=0;
for($i = 1; $i
By Jonas Birgander on 11.06.06 7:50 am | Permalink
If You need java class to convert from 10 to 13-digit ISBN no use my free source on my WEB page http://www.nofate.info?menu=5
Have a nice day
By Lukasz Skowron on 12.28.06 7:52 am | Permalink
Hi! Very nice site! Thanks you very much! qfEIKafpsRX
By SVCHRE2ur3 on 01.12.07 5:24 am | Permalink
Hi,
thanks for this PHP port and for the useful comments. I wonder if there is a case where the check digit of a ISBN-13 could be ‘x’ or ‘X’. From this page : http://en.wikipedia.org/wiki/ISBN#Check_digit_in_ISBN_13 I think it’s impossible. It can only be a decimal digit from 0 to 9.
So, if I’m right, the isbn_gettype should be :
function isbn_gettype($isbn) {
$isbn = trim($isbn);
if (preg_match(’%[0-9]{13}?%s’, $isbn)) {
if (isbn_validatettn($isbn)==1){
return 13;
} else {return(-1);}
} else if (preg_match(’%[0-9]{9}?[0-9Xx]%s’, $isbn)) {
if (isbn_validateten($isbn)==1){
return 10;
} else {return -1;}
} else {
return -1;
}
}
and the isbn_validatettn function should be :
function isbn_validatettn($isbn) {
$isbn = trim($isbn);
$chksum = substr($isbn, -1, 1);
$isbn = substr($isbn, 0, -1);
$sum = isbn_genchksum13($isbn);
if ($chksum == $sum){
return 1;
}else{
return 0;
}
}
By andras on 01.14.07 6:45 am | Permalink
I just realize that the question mark has no sense in :
if (preg_match(’%[0-9]{13}?%s’, $isbn))
so it should be :
if (preg_match(’%[0-9]{13}%s’, $isbn))
By andras on 01.14.07 8:32 am | Permalink
One more time, sorry. I think the test should be :
if (preg_match(’%^[0-9]{13}$%s’, $isbn))
By andras on 01.14.07 6:26 pm | Permalink
Hi,
Thanks for producing this, I found a javascript version, but wanted a PHP version for my site.
This code has saved me a lot of time.
Thanks again!
By OracleHome on 01.31.07 12:54 pm | Permalink
cannot get this working.
just including it throws:
Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or ‘}’ in /usr/home/www/htdocs/test/ISBN_script.php on line 11
so I changed public function to function and (not surprisingly)
Fatal error: Undefined class name ’self’ in /usr/home/www/htdocs/test/ISBN_script.php on line 13
By huh on 02.13.07 1:04 am | Permalink
This is the collection of ISBN code I’m actively using, compiled from the original code and the comments.
I added the isnb_dashes($isbn) function, which accepts a 10 or 13 digit ISBN number and adds the dashes. This does not check the validity of the string, it just returns it. If it isn’t 10 or 13 characters long, the function returns false.
function isbn_convert($isbn) {
$isbn2 = substr("978" . trim($isbn), 0, -1);
$sum13 = isbn_genchksum13($isbn2);
$isbn13 = "$isbn2-$sum13";
return ($isbn13);
}
function isbn_gettype($isbn) {
$isbn = trim($isbn);
if (preg_match('%[0-9]{12}?[0-9Xx]%s', $isbn)) {
if (isbn_validatettn($isbn)==1){
return 13;
} else {return(-1);}
} else if (preg_match('%[0-9]{9}?[0-9Xx]%s', $isbn)) {
if (isbn_validateten($isbn)==1){
return 10;
} else {return -1;}
} else {
return -1;
}
}
function isbn_validateten($isbn) {
$isbn = trim($isbn);
$chksum = substr($isbn, -1, 1);
$isbn = substr($isbn, 0, -1);
if (preg_match('/X/i', $chksum)) { $chksum="10"; }
$sum = isbn_genchksum10($isbn);
if ($chksum == $sum){
return 1;
}else{
return 0;
}
}
function isbn_validatettn($isbn) {
$isbn = trim($isbn);
$chksum = substr($isbn, -1, 1);
$isbn = substr($isbn, 0, -1);
if (preg_match('/X/i', $chksum)) { $chksum="10"; }
$sum = isbn_genchksum13($isbn);
if ($chksum == $sum){
return 1;
}else{
return 0;
}
}
function isbn_genchksum13($isbn) {
$t = 2;
$isbn = trim($isbn);
$b=0;
for($i = 1; $i genchksum10($isbn2);
if ($sum10==10) {$sum10='X';}
$isbn10 = $isbn2.$sum10;
return ($isbn10);
}
## ISBN Add Dashes
function isbn_dashes($isbn) {
switch(strlen($isbn)):
case 13:
return
substr($isbn,0,3)."-"
.substr($isbn,3,1)."-"
.substr($isbn,4,3)."-"
.substr($isbn,7,5)."-"
.substr($isbn,12,1);
break;
case 10:
return
substr($isbn,0,1)."-"
.substr($isbn,1,3)."-"
.substr($isbn,4,5)."-"
.substr($isbn,9,1);
break;
default: return false; break;
endswitch;
}
By Adam on 02.22.07 2:34 pm | Permalink
Hi Adam, your function
isbn_dashes();does not place the hyphens on the right place most of the times. It may be correct with some US-ISBN numbers, I doubt you’ve read the official guidelines:Hyphenation Instructions
By Thijs on 03.18.07 12:03 pm | Permalink
Thijs, thanks for the pointer. I’m in the US, dealing with American books. It never occurred to me that there would be a standard for hyphenating or that international books would be hyphenated differently.
I poked around the site and didn’t see a guide for the 13 digit numbers. I assume its the same as 10, except with the dash added after the opening 978.
I will update my function when I have some free time, and I’ll post the code here.
By Adam on 03.27.07 4:44 pm | Permalink
Am I crazy or is none of the code on this page complete?
Lines like this: for($i = 1; $i genchksum10($isbn2);
and blocks of code that end like this:
function isbn_genchksum13($isbn) {
$isbn = trim($isbn);
for ($i = 0; $i
Surely can’t be correct. What is going on here? Is everyone just not good at copy and pasteing? Am I the idiot? I’m baffled.
By Nicholas on 04.16.07 4:26 pm | Permalink
Here is a txt version
http://tinyurl.com/28ncrk
By Adam on 05.04.07 5:26 pm | Permalink
I have quite a complete ISBN test tool that does all of the above and also does GTIN-14. It’s for php5, but could likely be backported to php4 fairly easily.
If anyone is interested you’ll find it at http://www.phpclasses.org/browse/package/1707.html
It’s just called ISBNcheck (not a clever name, but it works)
kapn
By Keith Nunn on 02.21.08 10:01 am | Permalink
Leave a comment
Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>