Pages

2011年5月14日土曜日

チェックディジットを計算してみる

JANコードの末桁は、チェックデジットと呼ばれる読み取り防止のための数字だ。
計算方法は、モジュラス10 ウエイト3-1 (一括) と呼ばれる。
アルゴリズム名がmodulus10で、奇数桁計3倍、偶数桁 1倍、足し方が一括?だから!
JANバーコードのアルゴリズムは、末尾から奇数桁に3、偶数桁に1を掛けてから単純に足し算し、結果を10で割った余り(剰余)を求め、10からその剰余を引いた値をチェックディジットとして用いている。
例えば「49722536」というJAN8バーコードを例にすると、末尾6がチェックディジットである。この6はどう求められているかというと、次のように求めているわけである。
奇数桁の算出(4+7+2+3)×3→48
偶数桁の加算48+(9+2+5)→64
10から(2)の10の剰余を引く10-4→6
もって、ディジット6は正当であることが求められた。

rubyで書いてみた。
  1. # check_digit.rb   
  2. # check digit / modulus10 wait 3-1 (MOD 10)  
  3. # for JAN (EAN), ISBN-13  
  4. # usage : $ check_digit.rb <number>  
  5.   
  6. exit unless ARGV.size == 1  
  7. num = ARGV.shift # チェックデジットを取得したい数字をセット  
  8. exit unless [7,12].include?(num.size) # JAN(EAN)は、8桁,13桁のいずれか。C/D分を減らす。  
  9.   
  10. pos = total_even = total_odd = 0 # even 偶数、odd 奇数  
  11. # C/D分の桁を補完し、文字列を逆にして桁を1桁目から取る。split(//)で1文字単位に分割。  
  12. (num + '0').reverse.split(//).each do |s|  
  13.   pos += 1  
  14.   # 偶数桁、奇数桁を判断し、それぞれ加算。  
  15.   (pos % 2) == 0 ? total_even += s.to_i : total_odd += s.to_i  
  16. end  
  17. p 10 - (total_even * 3 + total_odd * 1) % 10 # ウエイト付けて、補数にして  
  18.   
  19. </number>  
# check_digit.rb 
# check digit / modulus10 wait 3-1 (MOD 10)
# for JAN (EAN), ISBN-13
# usage : $ check_digit.rb 

exit unless ARGV.size == 1
num = ARGV.shift # チェックデジットを取得したい数字をセット
exit unless [7,12].include?(num.size) # JAN(EAN)は、8桁,13桁のいずれか。C/D分を減らす。

pos = total_even = total_odd = 0 # even 偶数、odd 奇数
# C/D分の桁を補完し、文字列を逆にして桁を1桁目から取る。split(//)で1文字単位に分割。
(num + '0').reverse.split(//).each do |s|
  pos += 1
  # 偶数桁、奇数桁を判断し、それぞれ加算。
  (pos % 2) == 0 ? total_even += s.to_i : total_odd += s.to_i
end
p 10 - (total_even * 3 + total_odd * 1) % 10 # ウエイト付けて、補数にして



実行結果は、以下の通り。
[baker@www work]$ ruby check_digit.rb 4972253
6  # 最終コードは、49722536 
[baker@www work]$ ruby check_digit.rb 491012345064
3  # 最終コードは、4910123450643

0 件のコメント:

コメントを投稿