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