From 0c169039893c8e6e89c124715f3ca1c59c8c38b9 Mon Sep 17 00:00:00 2001 From: George F Murphy Date: Thu, 17 Nov 2011 08:22:17 -0600 Subject: [PATCH] first attempt at recursive solution --- luhnybin.rb | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ mask.sh | 2 +- 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100755 luhnybin.rb diff --git a/luhnybin.rb b/luhnybin.rb new file mode 100755 index 0000000..03fcc0c --- /dev/null +++ b/luhnybin.rb @@ -0,0 +1,76 @@ +#!/usr/bin/env ruby +class Luhnybin + MINIMUM = 14 + SUMMED_DOUBLES = [0, 2, 4, 6, 8, 1, 3, 5, 7, 9].freeze + + def initialize(text) + @text = text.unpack('c*') + filter + end + + def text + @text.pack('c*') + end + + private + def filter(start=0, index=0, digits=[]) + return 0 if index == @text.length || digits.length > 16 + + count = luhn(digits) + return count if count > 0 + + char = @text[index] + digit = digit?(char) + + if digit + value = char - ?0 + digits.unshift(value) + elsif !separator?(char) + start = index + digits.clear + end + + lc = filter(start, index + 1, digits) + if lc > 0 && digit + @text[index] = ?X + lc -= 1 + end + return lc + end + + def luhn(digits) + length = digits.length + return 0 if length < MINIMUM + + length.downto(MINIMUM) do |n| + i = 0 + sum = digits[0,n].reduce(0) do |tot, d| + tot += i.even? ? d : SUMMED_DOUBLES[d] + i += 1 + tot + end + return n if sum % 10 == 0 + end + return 0 + end + + def digit?(char) + char.between?(?0, ?9) + end + + def separator?(char) + char == ?- || char == 32 + end +end + +class String + def mask_cc_number + Luhnybin.new(self).text + end +end + +if __FILE__ == $0 + STDIN.each do |line| + STDOUT << line.mask_cc_number + end +end diff --git a/mask.sh b/mask.sh index 652565b..9764432 100755 --- a/mask.sh +++ b/mask.sh @@ -1,4 +1,4 @@ #!/bin/sh # Call your program here instead of cat. -cat +./luhnybin.rb