The entries 2004/hibachi and 2005/mynx have unobfuscated code now. 2004/hibachi has a configure script that is used along the lines of the original entry (with some adjustments and fixes) and the hibachi.alt.c had to have ctype.h included too. The directory src/localhost was copied to src-alt/localhost but the rest of src/ was from Anthony. The Makefile had to be updated to build this version. 2005/mynx does have a configure script but it is, just like the original entry, unused and so the unobfuscated (in source-alt/) is also unused. The mynx.alt.c was changed to mynx.alt2.c and the unobfuscated code was made mynx.alt.c. Updated manifest, rebuilt .entry.json and index.html files. After a question is answered and taken care of (in one of 199[1-3]/ant - not sure which one) issue #2513 can possibly be closed as complete (though the manifest updates will have to be looked at more when 2004 and 2005 are reviewed).
151 lines
3.5 KiB
Ruby
151 lines
3.5 KiB
Ruby
#
|
|
# LUHN.rb
|
|
#
|
|
# Copyright 2000, 2004 by Anthony Howe. All rights reserved.
|
|
#
|
|
|
|
class LUHN
|
|
def LUHN.base(str, radix)
|
|
if radix < 2 then
|
|
return nil
|
|
end
|
|
|
|
num = 0
|
|
str.downcase!
|
|
str.each_byte do |byte|
|
|
i = "0123456789abcdefghijklmnopqrstuvwxyz".index(byte)
|
|
if i.nil? || radix <= i then
|
|
return nil
|
|
end
|
|
num = num * radix + i
|
|
end
|
|
|
|
return num
|
|
end
|
|
|
|
#
|
|
# Internal routine that computes the LUHN sum.
|
|
#
|
|
# The LUHN Algorithm ("mod 10 Double-Add-Double"):
|
|
#
|
|
# 1. Position from right 8 7 6 5 4 3 2 1
|
|
# ------------------------------
|
|
# Number string 4 8 9 5 1 3 1 3
|
|
# x2 even positions 2 1 2 1 2 1 2 1
|
|
# ------------------------------
|
|
# Add odd positions & 8 +8 +1+8 +5 +2 +3 +2 +3
|
|
# add digits of doubled
|
|
# positions
|
|
#
|
|
# Sum 40
|
|
#
|
|
# Number is valid if sum is a multiple of 10.
|
|
#
|
|
#
|
|
# 2. Alpha-numeric ISIN U S 3 8 3 8 8 3 1 0 5 1
|
|
# (ISO 6166) -----------------------------------------
|
|
# base 36 digits 30 28 3 8 3 8 8 3 1 0 5 1
|
|
# -----------------------------------------
|
|
# consider digit string 3 0 2 8 3 8 3 8 8 3 1 0 5 1
|
|
# & x2 even digits from 2 1 2 1 2 1 2 1 2 1 2 1 2 1
|
|
# -----------------------------------------
|
|
# 6 0 4 8 6 8 6 8 16 3 2 0 10 1
|
|
# -----------------------------------------
|
|
# sum the digits of 6 +0 +4 +8 +6 +8 +6 +8+1+6+3 +2 +0+1+0+1
|
|
#
|
|
# Sum 60
|
|
#
|
|
# Number is valid if sum is a multiple of 10.
|
|
#
|
|
def LUHN.sum(str)
|
|
if ! str.instance_of?(String) || str.length < 1 then
|
|
return nil
|
|
end
|
|
|
|
total = 0
|
|
even = false
|
|
str = str.reverse.downcase
|
|
|
|
# Working right to left...
|
|
str.each_byte do |byte|
|
|
# Convert base36 digit to a base10 value.
|
|
digit36 = base(byte.chr, 36)
|
|
if digit36.nil? then
|
|
return nil
|
|
end
|
|
|
|
# For each base10 digit of a base36 digit...
|
|
begin
|
|
digit10 = digit36 % 10
|
|
|
|
if even then
|
|
# Multiply even digits by 2.
|
|
digit10 <<= 1
|
|
|
|
# Sum digits of product.
|
|
if 10 <= digit10 then
|
|
digit10 -= 9
|
|
end
|
|
end
|
|
|
|
# Add digits of product to total.
|
|
total += digit10
|
|
|
|
# Next digit.
|
|
digit36 = (digit36 / 10).floor
|
|
|
|
# Toggle from digit to digit.
|
|
even = !even
|
|
end while 0 < digit36
|
|
end
|
|
|
|
return total
|
|
end
|
|
|
|
#
|
|
# Return true if the string of digits is valid.
|
|
# Assumes LUHN check digit is right most digit.
|
|
#
|
|
def LUHN.valid?(str)
|
|
if ! str.instance_of?(String) || str.length < 2 then
|
|
return false
|
|
end
|
|
|
|
total = sum(str)
|
|
|
|
return total.nil? ? false : (total % 10) == 0
|
|
end
|
|
|
|
#
|
|
# Return the LUHN check digit (mod 10) for the
|
|
# given string of digits; otherwise nil on error.
|
|
#
|
|
def LUHN.generate(str)
|
|
if ! str.instance_of?(String) || str.length < 1 then
|
|
return nil
|
|
end
|
|
|
|
total = sum(str + '0')
|
|
|
|
return total.nil? ? nil : (10 - (total % 10)) % 10
|
|
end
|
|
end
|
|
|
|
if $DEBUG && $0 == 'LUHN.rb' then
|
|
def generate(str, expect)
|
|
digit = LUHN.generate(str)
|
|
puts(str + "-" + digit.to_s + ' ' + (digit == expect).to_s)
|
|
end
|
|
def validate(str)
|
|
puts(str + ' ' + LUHN.valid?(str).to_s)
|
|
end
|
|
|
|
generate('1', 8)
|
|
generate('12', 5)
|
|
generate('123', 0)
|
|
generate('A', 9)
|
|
generate('AB', 6)
|
|
|
|
validate('AB6')
|
|
end
|