圖書與期刊各有一套編號體系,兩者都帶校驗位,做法卻不完全相同。本文從最後一位的由來說起,說明兩套體系的差別、校驗位為什麼可能是字母、號段是怎麼逐級分配的,以及為什麼同一本書的兩個號碼要分別驗。
ISBN 和 ISSN 的校驗位怎麼算?
兩者都是「由其餘位算出最後一位」的結構,差異在於套用的加權方式與模數。書號用的是一種加權求和後取模的做法,刊號用的是另一種;兩者都不需要連線,也不需要查任何資料庫。
書號有兩種長度並存,分別對應不同的世代。較早的一種與較晚的一種,校驗位的算法不一樣,這也是為什麼同一本書的兩個號碼不能沿同一段程式碼處理。
| 體系 | 校驗位算法家族 | 最後一位的型態 |
|---|---|---|
| 較早的書號 | 加權求和取模(一種模數) | 通常是數字 |
| 較晚的書號 | 與商品條碼同源的加權方式 | 通常是數字 |
| 刊號 | 加權求和取模(另一種模數) | 數字或字母 |
表格刻意不寫權重與模數的具體數值。實作時請照官方說明取參數,因為這些參數在體系之間流傳著不少抄錯的版本。
另一個容易忽略的點是校驗位的來源。它是由號碼前面那些位算出來的,而不是查表得來的;因此只要位數與字元正確,任何人都能在本機算出相同的結果。這也是為什麼書號可以在沒有連線的環境裡當場檢查。
兩套書號體系的差別
最實際的差別有三個:長度、校驗位的算法、以及能不能與商品條碼體系互通。較晚的體系與商品條碼共用同一套加權邏輯,因此它的校驗位可以由同一支函式算出;較早的體系則需要獨立的一支。
這帶來一個常見的實作問題:程式裡只留了一支書號校驗函式,遇到另一種長度就整串判錯。加上長度分流之後,這個問題通常當場消失。
第二個差別是連字號的位置。兩種體系的分組方式不同,而同一個體系在不同年代、不同來源也可能出現不同的分組。因此連字號不該被當成判定的依據,只能當成顯示層的裝飾。
第三個差別是與既有系統的相容性。較晚的體系與商品條碼同源,因此在零售與倉儲系統裡可以直接沿用同一套掃描與比對邏輯;較早的體系則常需要單獨的欄位與轉換步驟。若你的系統同時處理圖書與其他商品,這個差別會直接影響資料模型的設計。
校驗位可能是字母 X 的情況
用模數十一那一類算法的體系,餘數可能落在一個需要以字母表示的值上,慣例是用大寫的 X 代表。這不是錯誤,而是算法本身允許的取值。
這個特性對輸入流程的影響很具體:只允許數字的欄位會把這類合法的號碼判成格式錯誤。表單的字元集必須依體系設定,而不是全部統一成數字。
處理時還有兩個容易忽略的點。一是大小寫:使用者可能輸入小寫的 x,比對前應該先統一成同一個大小寫。二是位置:字母只可能出現在最後一位,若中間出現字母,那就是輸入問題,而不是體系允許的情況。
還有一個實作細節:當你把字母統一成同一個大小寫時,回報給使用者的錯誤訊息也應該保留他原本輸入的字元。若訊息裡顯示的是你正規化過的值,使用者會以為自己打錯了,反而更難找到問題。
號段是怎麼分配的
兩種體系的號碼都不是隨機的,而是由不同層級的機構逐級分配下來的。最前面的一段標示所屬的群體或地區,接著是由各層級分配給出版者或刊物的段,最後才是流水號與校驗位。
這個結構解釋了一個常見的疑惑:為什麼兩本書的號碼前面很像,後面卻完全不同。前面相同通常代表它們落在同一個分配層級之下,不代表內容相關,也不代表出版時間接近。
也因為是逐級分配,段位會隨著分配狀況調整。當某一層級的號段用盡,後續的號碼就會落到別的段上。這不是錯誤,而是分配制度運作的結果。
對資料分析來說,這意味著不能把號段當成穩定的分類標籤。同一家出版者在不同時期拿到的段可能不同,因此用號段統計出版量或推測年份,都會得到偏差。需要這些資訊時,應該回到出版者或刊物的登記資料,而不是從號碼反推。
為什麼換過號的書要兩個都驗?
當體系從較早的一種過渡到較晚的一種時,同一本書可能同時擁有兩個號碼。舊號在舊系統裡有效,新號在新系統裡有效,兩者都不該被當成錯的。
對使用者來說,這意味著查詢時可能要兩個都試;對開發者來說,這意味著欄位不能只保留一個。若只留一個欄位,就會有一半的舊資料在遷移時遺失。
比較穩健的做法是把兩個號碼都存下來,並在顯示時標明各自的體系。這樣既不會覆蓋歷史資料,也不會讓使用者在兩個看起來都合理的號碼之間無所適從。
還有一種情況是標籤已經印好了。書脊或封底上的號碼在印製後無法更改,因此一段時間內市面上會同時流通兩種標示。查詢系統若只接受其中一種,就會有一批使用者查不到明明存在的資料。
給開發者:輸入正規化與連字號
書號與刊號的處理幾乎全在正規化與分流上,算法本身反而簡單。建議的順序:
- 去掉空白與連字號,只留體系允許的字元。
- 統一字母的大小寫,再判斷長度。
- 依長度選定算法與參數,不要讓呼叫端自己指定。
- 保留原始輸入字串,方便回報錯誤時對照。
- 兩個世代的號碼都要能通過,不要只驗其中一種。
把它與商品條碼放在一起看會更清楚:EAN 與 UPC 條碼校驗位講的是同一支加權邏輯在商品上的用法,而校驗位演算法家族整理了各支算法的共通骨架。
還有一點值得提醒:不要把連字號當成判定依據。使用者從不同來源複製來的號碼,分組可能不一樣,但去掉連字號之後其實是同一個值。以連字號判斷反而會製造假錯誤。
下一步
先確認你的系統裡書號與刊號各自用了哪一支校驗函式,再檢查它們有沒有依長度分流。接著用號碼校驗工具貼上明顯是構造值的示範號碼,同時測含字母與不含字母兩種情況,確認錯誤提示沒有把合法的字母位判成格式錯誤。如果你的資料同時含圖書與其他商品,也順便確認條碼那條路徑沒有被書號的分流邏輯影響。
文中的示範號碼是為了說明校驗位的由來而編造的,不對應任何真實圖書或期刊,也不代表任何出版物實際存在。