Last active
April 23, 2018 23:08
-
-
Save yb66/f9784cb34440c498b715d26f54af5852 to your computer and use it in GitHub Desktop.
Luhn algorithm with the broken Syncthing implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Implemented because Syncthing (kind of) uses it | |
# @example | |
# @luhn = Luhn.new Base32.table | |
# @luhn.check_character "P56IOI7MZJNU2" | |
# # => "S" | |
class Luhn | |
def initialize alphabet | |
@alphabet = alphabet | |
@table_alpha = Hash[ @alphabet.split(//).zip(0 .. @alphabet.length - 1) ] | |
@table_code = Hash[ (0 .. @alphabet.length - 1).zip(@alphabet.split(//))] | |
end | |
attr_reader :alphabet, :table_alpha, :table_code | |
def n | |
@n ||= @alphabet.length | |
end | |
FACTOR = 2 | |
# Starting from the right and working leftwards is easier since | |
# the initial "factor" will always be "2" | |
def check_character input, factor=FACTOR | |
sum = input.reverse.each_char.inject(0) do |sum,char| | |
addend = factor * @table_alpha[char] | |
# Alternate the "factor" that each "codePoint" is multiplied by | |
factor = (factor == 2) ? 1 : 2 | |
# Sum the digits of the "addend" as expressed in base "n" | |
sum += Integer(addend / n) + (addend % n) | |
end | |
# Calculate the number that must be added to the "sum" | |
# to make it divisible by "n" | |
remainder = sum % n | |
checkcode = (n - remainder) % n | |
@table_code[checkcode] | |
end | |
# @see https://forum.syncthing.net/t/v0-9-0-new-node-id-format/478/7 | |
# @example | |
# @luhn = Luhn.new Base32.table | |
# @luhn.check_for_syncthing "P56IOI7MZJNU2" | |
# # => "Y" | |
def check_for_syncthing input | |
check_character input.reverse, 1 | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment