コマンドライン上で、手軽にISBNから本の名前を調べたいというところから始まったのですが、「ISBN - Wikipedia」を見ると、ISBN-13とISBN-10は相互変換できるんですね。簡単そうなので、実際、やってみました。
ISBN-13 => ISBN-10への変換例
9784480064707で試してみます。
(1) 左3桁と1桁目を取ります。
9784480064707 => 448006470
(2) 「モジュラス11 ウェイト10-2」という計算方法でチェックディジットを求めます。
左側の桁から10,9,8…,2を掛けてそれらの和を取り、和を11で割って出た余りを11から引きます。このときの計算結果が10になった場合、10の代わりにX(アルファベットの大文字)を用い、11になった場合は0にします。
4*10 + 4*9 + 8*8 + 0*7 + 0*6 + 6*5 + 4*4 + 7*3 + 0*2 = 207 207 / 11 = 18 あまり 9 11 - 9 = 2 (チェックディジットが求まりました。)
(3) チェックディジットを右端にくっつけて完了
448006470
ISBN-10 => ISBN-13への変換例
上記で求めた448006470で試してみます。
(1) 接頭記号978を左端にくっつけます*1。
978448006470
(2) 「モジュラス10 ウェイト3・1(モジュラス10 ウェイト3)」という計算法でチェックディジットを求めます。
一番左側の桁から順に1、3、1、3…を掛けてそれらの和を取り、和を10で割って出た余りを10から引きます。これがチェックディジットになりますが、先ほどの和が10で割り切れた場合のチェックディジットは10 - 0 = 10ではなく、0になります。
9*1 + 7*3 + 8*1 + 4*3 + 4*1 + 8*3 + 0*1 + 0*3 + 6*1 + 4*3 + 7*1 + 0*3 = 103 103 / 10 = 10 あまり 3 10 - 3 = 7 (チェックディジットが求まりました。)
(3) チェックディジットを右端にくっつけて完了
9784480064707
isbn2book_title.rb
#!/usr/bin/env ruby require 'nokogiri' require 'open-uri' module IsbnConv # ISBN13 => ISBN10 def self.to10 isbn13 isbn = %r{^\d{3}(\d+?)\d$}.match(isbn13.gsub(/[^\d]/,''))[1] r = [*2..10].reverse.zip(isbn.split(//).map(&:to_i)).map{|e| e[0] * e[1] }.reduce(:+) % 11 isbn += case n = 11 - r when 11 '0' when 10 'x' else n.to_s end end # ISBN10 => ISBN13 def self.to13 isbn10 isbn = "978" + isbn10.gsub(/[^\d]/,'').gsub(/\d$/,'') r = isbn.split(//).map(&:to_i).zip([1,3].cycle).map{|e| e[0] * e[1] }.reduce(:+) % 10 isbn + ((10 - r) % 10).to_s end end def get_book_title isbn10 url = "http://www.amazon.co.jp/gp/product/#{isbn10}" user_agent = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)' Nokogiri.HTML(open(url, 'User-Agent' => user_agent)).title end IsbnConv.to10 "9784480064707" # => "4480064702" IsbnConv.to13 "4480064702" # => "9784480064707" puts get_book_title "4480064702"
実行結果
$ ./isbn2book_title.rb Amazon.co.jp: 学問のすすめ 現代語訳 (ちくま新書): 福澤 諭吉, 斎藤 孝: 本
*1:979は考慮していません…。