PHPでISBNコードをASINコードに変換する

(1/1)
ASINは、Amazon.comが独自に決めた商品番号だ。
今回は、国際標準図書番号「ISBN」から、ASINへコード変換するプログラムを作ってみる。

サンプル・プログラムの実行例

PHPでISBNコードをASINコードに変換する

目次

サンプル・プログラム

圧縮ファイルの内容
isbn2asin.phpサンプル・プログラム本体。

ISBNコード

ISBN(International Standard Book Number)は国際標準図書番号とも呼ばれ、書籍を特定するための世界共通の番号体系である。
2006年(平成18年)12月31日までは10進数10桁の番号が用いられていたが、2007年(平成19年)以降には10進数13桁の番号へ移行した。ここでは現行規格を中心に説明する。

ISBNコードは10進数13桁からなり、その内容は下記の通りである。
内容
13-11識別番号(978または979)
10グループ記号(出版国などを表す数字で、日本は4)
9-6出版者記号
5-2書名記号
1チェックデジット
たとえば、「楽しいPHP入門」(クジラ飛行机/インプレスジャパン/2009年(平成21年)11月)という書籍のISBNコードは 9784844327882 である。これを分解すると下記のようになる。
内容
識別番号978
グループ記号4
出版者記号8443
書名記号2788
チェックデジット2
出版者番号 8443 はインプレスコミュニケーションズに与えられた番号である。

チェックデジットはモジュラス10 ウェイト3 という方式である。以下のように計算する。
  1. チェックデジットをのぞく一番左側の桁から順に1,3,1,3を掛けて、それらの和を取る。
  2. 和を10で割った余りを10から引く。ただし10で割って出た余りの下1桁が0の場合は0とする。
これを上記の書籍に適用すると、


9×1+7×3+8×1+4×3+8×1+4×3+4×1+3×3+2×1+7×3+8×1+8×3=138
138%10=8
10-8=2


となり、チェックデジットの 2 を得ることができる。

ちなみに、旧規格(2007年12月31日まで)は10進数10桁であるが、グループ記号、出版者記号、書名記号は現行規格と同じである。チェックデジットの計算方法は異なる(モジュラス11 ウェイト10-2)。

ASINコード

ASIN(Amazon Standard Identification Number)は、Amazon.comが独自に決めた商品番号のことで、書籍についてはISBNの旧規格と同じ番号であった。

ISBNの現行規格についても、識別番号が978であるものについては、桁数10-2は同一である。ただしチェックデジットの計算方法がモジュラス11 ウェイト10-2であるため、最後の1桁の数字が異なる。

モジュラス11 ウェイト10-2方式は、以下のように計算する。
  1. チェックデジットを除いた左側の桁から10,9,8‥‥2を掛けてそれらの和を取る。
  2. 和を11で割って出た余りを11から引く。
前述の「楽しいPHP入門」のASINコードは 4844327887 である。このチェックデジットを求めようとすると、


4×10+8×9+4×8+4×7+3×6+2×5+7×4+8×3+8×2=268
268%11=4
11-4=7


となり、チェックデジットの 7 を得ることができる。

ISBNとASINの関係

9 7 8 ISBNコード 4 8 4 4 3 2 7 8 8 2 4 8 4 4 3 2 7 8 8 7 ASINコード 13 10 5 2 1

解説:ISBNコードをASINコードに変換する

0151: /**
0152:  * ISBNコードをASINコードに変換する
0153:  * @param string $isbn ISBNコード(10進数10桁or 13桁)
0154:  * @return string ASINコード(10進数10桁)/FALSE:変換に失敗
0155: */
0156: function isbn2asin($isbn) {
0157:     //旧ISBNコードの場合はそのまま返す
0158:     if (preg_match('/^[0-9]{9}[0-9X]$/', $isbn) == 1) {
0159:         if (cd11($isbn) != substr($isbn, 9, 1))      return FALSE;
0160:         return $isbn;
0161:     }
0162: 
0163:     //入力値チェック
0164:     if (preg_match('/^[0-9]{13}$/', $isbn) != 1)   return FALSE;
0165:     if (cd10($isbn) != substr($isbn, 12, 1))     return FALSE;
0166:     if (preg_match('/^978/', $isbn) == 0)          return FALSE;
0167: 
0168:     $code = substr($isbn, 3, 10);        //10-1桁目を取り出す
0169:     $cd = cd11($code);
0170: 
0171:     return substr($isbn, 3, 9) . $cd;
0172: }

0118: /**
0119:  * チェックデジットの計算(モジュラス11ウェイト10-2)ASIN用
0120:  * @param string $code 計算するコード(最下位桁がチェックデジット)
0121:  * @return intチェックデジット
0122: */
0123: function cd11($code) {
0124:     $cd = 0;
0125:     for ($pos = 10; $pos >= 2; $pos--) {
0126:         $n = substr($code, (10 - $pos), 1);
0127:         $cd += $n * $pos;
0128:     }
0129:     $cd = $cd % 11;
0130:     $cd = 11 - $cd;
0131:     if ($cd == 10)  $cd = 'X';
0132:     if ($cd == 11)  $cd = '0';
0133:     return $cd;
0134: }

0136: /**
0137:  * チェックデジットの計算(モジュラス10ウェイト3)
0138:  * @param string $code 計算するコード(最下位桁がチェックデジット)
0139:  * @return intチェックデジット
0140: */
0141: function cd10($code) {
0142:     $cd = 0;
0143:     for ($pos = 13; $pos >= 2; $pos--) {
0144:         $n = substr($code, (13 - $pos), 1);
0145:         $cd += $n * (($pos % 2) == 0 ? 3 : 1);
0146:     }
0147:     $cd = $cd % 10;
0148:     return ($cd == 0) ? 0 : 10 - $cd;
0149: }

変換処理自体は、前述のISBNおよびASINの定義にしたがって計算しているだけである。
ただ、入力値のチェックは細かく行っている。

入力値が10進数10桁なら旧ISBNとして処理をする。この際、チェックデジットが合っているかどうか検査する。※10桁の末尾が 'X' の時に正常に動作しませんでした。クロメルさん、ご指摘及び改良方法の提案をありがとうございました(2015年9月20日)。

入力値が10進数13桁なら現行ISBNとして処理をする。この際、チェックデジットがあっているかどうか検査する。また、上位3桁が978以外の場合は変換処理ができないようにしてある。

チェックデジットの計算には、ユーザー関数cd10, cd11を用意した。

また、このプログラムはコマンドラインから単独で利用できるようにしてある。

isbn2asin.php?isbn=9784844327882


として実行すると、標準出力にASINコードのみが出力される。エラー発生時には 'ERROR' と出力する。

参考サイト

(この項おわり)
header