I know I believe in nothing but it is my sweet nothing.:2021年04月02日分

2021/04/02(Fri)

[プログラミング] ISBN Where To

NなんとかBSDにはユーザーを増やすためのHow Toは存在しないがムカつくdeveloperを都市ごと吹き飛ばすためのICBM Where Toがあるってしょーもないネタページ、さすがに悪趣味過ぎたか今はページ消えたのね。 まぁ更新なにそれ旨いののJPの和訳ページにはまだ 残ってるけどな!

いやまあ今日はICBMでもSSBNでもなくISBNの話なんですけどね…

書籍のISBNって、ワイの貧しい脳味噌にかすかに残った10桁番号時代の記憶では ここにある表の通り、出版社記号桁数に応じてブロック分けされてるから単純なロジックでハイフネーションできたと記憶してたのだが、 13桁化する前あたりに苦し紛れな枯渇対策で空き領域を無理矢理転用したりしたようで、酷いセグメンテーション起こしててもはや通用しないのだね。

なもんで ここにあるRangeMessage.xmlというデータベースを使って照合しないとダメっちゅーことを本日学びました、多分数日で忘れると思うけど。

ちなみにPythonだと isbn_hyphenate というモジュールがあって上記のRangeMessage.xmlを元にハイフネーションしてくれるのだが、いっこバグがあってISBN13は問題ないのだがISBN10を食わせると、13桁への変換に必要な末尾のチェックディジット再計算を忘れてるので、不正なISBN13が生成されるねこれ。 ダメじゃん。

ちなみにチェックディジットの再計算のロジックを今さっきWikiPedia読みながら書いてみたけど、こんな感じのコード組み込めばいいはず。

import re

def isbn10to13(isbn):
    if not re.match('^\d{9}(\d|X)$', isbn):
        raise Exception
    checkdigit = isbn[-1]
    isbn = isbn[:-1]
    digit = 0
    for i in range(0, 9):
        digit += int(isbn[i]) * (10 - i)
    digit = 11 - digit % 11
    if '0123456789X0'[digit] != checkdigit:
        raise Exception
    isbn = '978' + isbn
    digit = 0
    for i in range(0, 12):
        digit += int(isbn[i]) * [1, 3][i % 2]
    digit = 10 - digit % 10
    isbn += '01234567890'[digit]
    return isbn

なおワイは全人生でPython歴15分くらいの「ぜんぜんわからない俺は雰囲気でPythonを書いてる」人なので、修正及びプルリクは誰かに任せた。