Isbn 10 to 13 conversion

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Isbn 10 to 13 conversion

Post by raghavan20 »

I hope many of you would have heard about the new isbn 13 format. it is going to be used from jan 2007 and in the process of changing existing isbns.

according to isbn site, these are the following steps involved.
Example: 0-123456-47-9

Begin with prefix of “978”
Use the first nine numeric characters of the ISBN (include dashes)
978-0-123456-47-
Calculate the EAN check digit using the “Mod 10 Algorithm”
978-0-123456-47-2
ISBN-10 0-123456-47-9
ISBN-13 978-0-123456-47-2

My doubt is about the mod 10 algorithm on which set of numbers
1. 0-123456-47-9
or
2. 978-0-123456-47

i tried to use this Luhn algorithm from wikipedia, but does not seem to work on all isbns on both of the formats mentioned above.

Code: Select all

function checkLuhn(string purportedCC) {
     int sum := 0
     int nDigits := length(purportedCC)
     int parity := nDigits modulus 2
     for i from 0 to nDigits - 1 {
         int digit := integer(purportedCC[i])
         if i modulus 2 = parity
             digit := digit × 2
         if digit > 9
             digit := digit - 9 
         sum := sum + digit
     }
     return (sum modulus 10) = 0
 }
We can validate whether our conversion is correct or not by using this url from isbn site.
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Post by Mordred »

Since the checksum is used to detect incorrect codes, it only makes sense to calculate it on the NEW code.
You already have the checksum on the old one, and the required steps would not speak of it at all if you didn't have to recalc it.
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

alright, lets say you want to validate with new format,,,try this code...

Code: Select all

<?php

//for isbn: 0-375-71449-9;	expected checksum: 8;	otained checksum: 7	
echo "\n".validateisbn( "978-0-375-71449" )."\n";



  function validateisbn ( $isbn ) {
	$isbn=preg_replace( "[\-]", "", $isbn );  # strip dashes
	
	$isbnlength = strlen( $isbn );
	echo "\nlength: ".strlen( $isbn );
	
	$parity = $isbnlength % 2;
	$sum = 0;
	for( $i = 0; $i < $isbnlength; $i++ ) {
	
		$digit = $isbn[$i];
		if ( $i % 2 == $parity ) $digit = $digit * 2;
		if ( $digit > 9 ) $digit = $digit - 9;
		$sum = $sum + $digit;
		
	}
	
	
	$return = $sum % 10;
	return $return;
  }
?>
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

searching for isbn 13 to isbn 10 converter script

Post by raghavan20 »

i earlier found a class for converting isbn10 to isbn13 but i could not find code that converts isbn13 to isbn10.
i have googled and i could not find. please let me know if you know or find one.


thanks.
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

it is solved.
i managed to take off 978 digits and the last digit off and replaced the last digit with isbn10 checksum.
thanks to all.
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

Your example ISBN is invalid, by the way. A valid isbn10 is: 0-123456-47-7

Here's what you're looking for:

Code: Select all

function isbn10to13($isbn10) {
	if(!checkLuhn($isbn10)){
		echo 'invalid input isbn';
		return false;	
	} 
	$isbn13 = '978-'.substr($isbn10,0,-1);
	for($i=0;$i<10;$i++){
		if(checkLuhn($isbn13.$i)) return($isbn13.$i);
	}
	echo 'unable to convert the isbn';
	return false;
}
function checkLuhn($number) {
	// Copyright (c) Richard Warrender. Licenced under the GFDL.
	// http://www.vividreflection.com/

	// Modified slightly by Kieran Huggins
	// http://kieran.ca

	$number = preg_replace('/\D/','',$number); 

	// Get total amount of digits to process
	$digitCount = strlen((String) $number);
	// Checksum must be zero to begin with
	$checksum = 0;

	// Loop round card number extracting digits
	for($i = 1; $i<=$digitCount; $i++) {
		// Extract digit number
		$digits[$i] = (int) substr($number, -$i, 1);

		// Check to see if this the luhn number, we need to double it
		if(($i%2) == 0) {
			// Double luhn digit
			$digit = $digits[$i] * 2;

			// If greater or equal to 10, then use sum of digits
			if($digit >= 10) {
				// Get first digit
				$firstDigit = substr($digit, 0, 1);
				// Get second digit
				$secondDigit = substr($digit, 1, 1);
				/// Add together and replace original luhn digit
				$digit = $firstDigit + $secondDigit;
			}

			// Reload back into array
			$digits[$i] = $digit;
		}
		// Keep a running total for use in checksum
		$checksum += $digits[$i];
	}

	if(($checksum % 10) == 0) {
		return true;
	} else {
		return false;
	}
}
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

thanks keiran and i appreciate your help.
i earlier found another class to convert from isbn 10 to 13.
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

Cool - If you post it others will be able to find it when Googling :-)
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

Kieran Huggins wrote:Cool - If you post it others will be able to find it when Googling :-)
here it is mate...
isbnconverter adapter

Code: Select all

class ISBNConverter{
	public static function convertISBN( $value, $to13=TRUE, $to10=FALSE ){

		//initialize 
			$IsbnConverter = new ISBN();
			$value = preg_replace( "#[^0-9a-zA-Z]#", "", $value );
			$result = NULL;
		
		//convert to 13
			if( $to13 === TRUE ){
				$result = $IsbnConverter->convert( $value );
			}
		
		//convert to 10
			if( $to10 === TRUE ){
				$temp = substr( $value, 3, 9 );
				$checksum10 = $IsbnConverter->genchksum10( $temp );
				if( $checksum10 == 10 ) $checksum10 = 'X';
				$result = $temp . $checksum10;
			}
			
		//return
			##echo $result;
			return $result;
		
	}
}
main isbn class

Code: Select all

<?php
/*
* @Version 1.0
* @Author John F. Blyberg <blybergj@aadl.org> - http://www.blyberg.net
* @Desc ISBN Class, adapted from ISBN.pm - http://www.manasystems.co.uk/isbnpm.html
*/

class ISBN {


	public function convert($isbn) {
		$isbn2 = substr("978" . trim($isbn), 0, -1);
		$sum13 = self::genchksum13($isbn2);
		$isbn13 = $isbn2.$sum13;
		return ($isbn13);
	}

	public function gettype($isbn) {
		$isbn = trim($isbn);
		if (preg_match('%[0-9]{12}?[0-9Xx]%s', $isbn)) {
			return 13;
		} else if (preg_match('%[0-9]{9}?[0-9Xx]%s', $isbn)) {
			return 10;
		} else {
			return -1;
		}
	}

	public function validateten($isbn) {
		$isbn = trim($isbn);
		$chksum = substr($isbn, -1, 1);
		$isbn = substr($isbn, 0, -1);
		if (preg_match('/X/i', $chksum)) { $chksum="10"; }
		$sum = &self::genchksum10($isbn);
		if ($chksum == $sum){
			return 1;
		}else{
			return 0;
		}
	}

	public function validatettn($isbn) {
		$isbn = trim($isbn);
		$chksum = substr($isbn, -1, 1);
		$isbn = substr($isbn, 0, -1);
		if (preg_match('/X/i', $chksum)) { $chksum="10"; }
		$sum = self::genchksum13($isbn);
		if ($chksum == $sum){
			return 1;
		}else{
			return 0;
		}
	}

	public function genchksum13($isbn) {
		$isbn = trim($isbn);
		$tb = 0;
		for ($i = 0; $i <= 12; $i++) {
			$tc = substr($isbn, -1, 1);
			$isbn = substr($isbn, 0, -1);
			$ta = ($tc*3);
			$tci = substr($isbn, -1, 1);
			$isbn = substr($isbn, 0, -1);
			$tb = $tb + $ta + $tci;
		}
		$tg = ($tb / 10);
		$tint = intval($tg);
		if ($tint == $tg) { return 0; }
		$ts = substr($tg, -1, 1);
		$tsum = (10 - $ts);
		return $tsum;
	}

	public function genchksum10($isbn) {
		$t = 2;
		$isbn = trim($isbn);
		$a = NULL; $b = NULL;
		for($i = 0; $i <= 9; $i++){
			$b = $b + $a;
			$c = substr($isbn, -1, 1);
			$isbn = substr($isbn, 0, -1);
			$a = ($c * $t);
			$t++;
		}
		$s = ($b / 11);
		$s = intval($s);
		$s++;
		$g = ($s * 11);
		$sum = ($g - $b); 
		return $sum;
	}

	public function printinvalid() {
		print "That is an invalid ISBN number";
		exit;
	}
	
}



?>
Post Reply