読者です 読者をやめる 読者になる 読者になる

Mae向きなブログ

Mae向きな日記のブログ版。ようやくこちらに移行してきました。

ISBN-10とISBN-13の相互変換

Ruby

コマンドライン上で、手軽に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は考慮していません…。