ISBNコードの確認・変換用PHP関数
June 1, 2011 – 4:15 pmいまさらという感じもしないわけでもないが、ISBNの新旧コード変換(13桁<->10桁)そしてチェックを行うPHP関数を作ったのでメモしておいた。
あわせて、この関数の仕様を明確にするため、サンプルコードを与えておいた。
書籍コードISBNについて、「書籍コードとアマゾンAPIによる検索」に(解説)記事を書いたことがある。アマゾンなどの書籍データを活用しようとすると、ISBNの変換とかチェック機能を持つ関数を作っておくと便利と思い、PHP関数を作った。
作成した関数の機能は以下のとおり:
- isbn10_To_Isbn13(): 10桁のISBNコードを引数とし、これを13桁に変換し関数値として返す。
- isbn_To_Isbn10(): 13桁もしくは10桁のISBNコードを引数とし、10桁のISBNコードを関数値として返す。(アマゾンのASINコードとして使用することを意識)
- chkdigit13(): 引数が13桁ISBNコードとして(桁数ならびにチェックディジットからみて)適正かどうか確認。
- chkdigit10(): 引数が10桁ISBNコードとして(桁数ならびにチェックディジットからみて)適正かどうか確認。
サンプル計算: 上記の4種の関数を組み合わせて作成したサンプル出力用コードと出力例;
サンプル出力用PHPコード(test_isbn.php):
<?php require_once('./isbn_converter.php' ); isbn_checker('412004193X'); isbn_checker('4120041936'); isbn_checker('978-4-306-07289-3'); isbn_checker('9784861721212'); isbn_checker('4-06-23497-2'); function isbn_checker($id_for_check) { echo "\nChecked ID: " . $id_for_check . "\n"; $chkd13 = chkdigit13($id_for_check); if ( $chkd13===0 ) echo $id_for_check . " is correct ISBN-13.\n"; else if ($chkd13===-1) echo $id_for_check . " has 13 digits but not correct checkdigit.\n"; if ( $chkd13===0 ) { $isbn10 = isbn_To_Isbn10( $id_for_check ); echo "ISBN10 of ISBN13(" . $id_for_check . ") is " . $isbn10 . ".\n"; } else if ( $chkd13===-2 ) { $chkd10 = chkdigit10($id_for_check); if( $chkd10 === 0 ) { echo $id_for_check . " is correct ISBN-10.\n"; $isbn13 = isbn10_To_Isbn13( $id_for_check ); echo "ISBN13 of ISBN10(" . $id_for_check . ") is " . $isbn13 . ".\n"; } else if ($chkd10===-1) echo $id_for_check . " has 10 digits but not correct checkdigit.\n"; else echo $id_for_check . " is neither ISBN10 nor ISBN13.\n"; } } ?>
出力例:
$ php test_isbn.php Checked ID: 412004193X 412004193X is correct ISBN-10. ISBN13 of ISBN10(412004193X) is 9784120041938. Checked ID: 4120041936 4120041936 has 10 digits but not correct checkdigit. Checked ID: 978-4-306-07289-3 978-4-306-07289-3 is correct ISBN-13. ISBN10 of ISBN13(978-4-306-07289-3) is 4306072894. Checked ID: 9784861721212 9784861721212 is correct ISBN-13. ISBN10 of ISBN13(9784861721212) is 4861721210. Checked ID: 4-06-23497-2 4-06-23497-2 is neither ISBN10 nor ISBN13.
作成した関数:
isbn_converter.php;
<?php //***************************************************************** //* isbn10_To_Isbn13( $isbn10 ) //*---------------------------------------------------------------- //* //* Argument: $isbn10 //* Return : $isbn13 //* //***************************************************************** function isbn10_To_Isbn13( $isbn10 ) { $char = str_split($isbn10); $char_out = array(); $j = 0; for ( $i=0; $i<sizeof($char); $i++ ) { if ( is_numeric($char[$i]) || $char[$i] === 'x' || $char[$i] === 'X' ) { $char_out[$j] = $char[$i]; $j = $j + 1; } } $sum = 0; for ( $j=0; $j<9; $j=$j+2 ) $sum = $sum + (int)$char_out[$j]; $sum = 3*($sum+7) + 17; for ( $j=1; $j<9; $j=$j+2 ) $sum = $sum + (int)$char_out[$j]; $amari = $sum % 10; $digit = 10 - $amari; $isbn13 = "978"; for ($i=0; $i<9; $i++) $isbn13 = $isbn13 . $char_out[$i]; if ($digit ===10) $digit=0; $isbn13 = $isbn13 . (string)$digit; return $isbn13; } //***************************************************************** //* isbn_To_Isbn10 ( $isbn ) //*---------------------------------------------------------------- //* //* Argument: $isbn //* (ISBN10(ASIN) or ISBN13) //* Return : $isbn10 //* (ASIN or ISBN10) //* //***************************************************************** function isbn_To_Isbn10 ( $isbn ) { $char = str_split($isbn ); // 10 letters assumed correct ASIN if ( sizeof($char) === 10 ) return $isbn; // $char_out = array(); $j = 0; for ( $i=0; $i<sizeof($char); $i++ ) { if ( is_numeric($char[$i]) ) { $char_out[$j] = $char[$i]; $j = $j + 1; } } if( $j === 10 ) for($i=0; $i<10; $i++) $char_isbn[$i]=$char_out[$i]; else { $j = 0; $sum = 0; for ( $i=3; $i<12; $i++ ) { $char_isbn[$j] = $char_out[$i]; $sum = (10 - $j) * (int)$char_isbn[$j] + $sum; $j = $j + 1; } $amari = $sum % 11; $digit = 11 - $amari; if ( $digit == 10 ) $char_isbn[$j] = 'X'; else if( $digit == 11 ) $char_isbn[$j] = '0'; else $char_isbn[$j] = (string)$digit; } $isbn10 = $char_isbn[0]; for ( $i=1; $i<10; $i++ ) $isbn10 = $isbn10 . $char_isbn[$i]; return $isbn10; } //***************************************************************** //* chkdigit13 ( $isbn13 ) //*---------------------------------------------------------------- //* Check ISBN-13: //* Argument: $isbn13 //* Return : 0 : correct //* -2 : Not 13 digits // -1 : Check digit is not correct //* //***************************************************************** function chkdigit13( $isbn13 ) { $char = str_split($isbn13); $char_out = array(); $j = 0; for ( $i=0; $i<sizeof($char); $i++ ) { if ( is_numeric($char[$i]) ) { $char_out[$j] = $char[$i]; $j = $j + 1; } } if( $j != 13 ) { /* echo "Error: Not 13 digits \n"; */ return -2; } $sum = 0; for ( $j=1; $j<12; $j=$j+2 ) $sum = $sum + (int)$char_out[$j]; $sum = 3*$sum; for ( $j=0; $j<12; $j=$j+2 ) $sum = $sum + (int)$char_out[$j]; $amari = $sum % 10; $digit = 10 - $amari; if($digit === 10 ) $digit = 0; if ( $char_out[12] === (string)$digit ) return 0; else { /* echo "Error: Check digit Not Correct! 0001 \n"; */ return -1; } } //***************************************************************** //* chkdigit10 ( $isbn10 ) //*---------------------------------------------------------------- //* //* Check ISBN-10: //* //* Argument: $isbn10 //* Return : 0 : Correct //* -2 : Error: Not 10 digits //* -1 : Check digit is not correct //* //***************************************************************** function chkdigit10( $isbn10 ) { $char = str_split($isbn10); $char_out = array(); $j = 0; for ( $i=0; $i<sizeof($char); $i++ ) { if ( is_numeric($char[$i]) || $char[$i]==='x' || $char[$i]==='X') { if( $char[$i] ==='X' ) $char[$i]='x'; $char_out[$j] = $char[$i]; $j = $j + 1; } } if ( $j !== 10 ) { /* echo "ERROR: Not 10 digits! \n"; */ return -2; } $j = 0; $sum = 0; for ( $i=0; $i<9; $i++ ) $sum=(10-$i)*(int)$char_out[$i]+$sum; $amari = $sum % 11; $digit = (string)(11-$amari); if ( $digit == '10' && $char_out[9] ==='x' || $digit=='11' && $char_out[9] === '0' || $digit === $char_out[9] ) return 0; else{ /* echo "ERROR: CheckDigit Not Correct!\n"; */ return -1; } } ?>
2 Responses to “ISBNコードの確認・変換用PHP関数”
isbn_converter.php で、
“`
if ( $digit == ’10’ && $char_out[9] ===’x’ || $digit==’11’ && $char_0ut[9] === ‘0’
“`
は、
“`
if ( $digit == ’10’ && $char_out[9] ===’x’ || $digit==’11’ && $char_out[9] === ‘0’
“`
の間違いではないでしょうか?
By developer on Sep 7, 2018
ご指摘のとおりです。
本文を修正をしておきました。
ありがとうございました。
なお、このバグによってISBN-10でcheck-digitが0のときエラーになってしまい。ISBNの値が正しくないとの判定をされてしまいます。例えば、4000612530をチェックしようとすると、
となります。
、
By yama on Sep 8, 2018