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