Skip to content

Instantly share code, notes, and snippets.

@davidoram
Created February 26, 2024 22:15
Show Gist options
  • Save davidoram/d6adf6cd24a23f3bbac108aaa27c00df to your computer and use it in GitHub Desktop.
Save davidoram/d6adf6cd24a23f3bbac108aaa27c00df to your computer and use it in GitHub Desktop.

Revisions

  1. davidoram created this gist Feb 26, 2024.
    83 changes: 83 additions & 0 deletions convert-card-number-to-barcode.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,83 @@
    #!/usr/bin/env ruby
    # Convert a FlyBuys card number to a barcode

    def get_check_sum_from_thirteen_digit_code(card_number)
    evens = 0
    odds = 0

    # Loop over all characters
    card_number.chars.each_with_index do |character, index|
    # Don't include the last character - 1
    break if index == card_number.length - 1

    # Convert to a number
    num = character.to_i

    if index.odd?
    evens += num
    else
    odds += num
    end
    end

    (10 - (((evens * 3) + odds) % 10)) % 10
    end

    def is_card_number_valid(card_number)
    # Implement your validation logic here
    true
    end

    def is_barcode_valid(barcode)
    return false unless barcode[0..2] == "264"
    return false unless barcode.length == 13
    return false unless barcode.chars.all? { |char| char =~ /[0-9]/ }
    return false unless is_checksum_valid(barcode)

    true
    end

    def is_checksum_valid(barcode)
    number_one = 0
    number_two = 0

    # Create number one
    (11).step(0, -2) do |i|
    char = barcode[i]
    val = char.to_i
    number_one += val
    end
    number_one *= 3

    # Create number two
    (0).step(12, 2) do |i|
    char = barcode[i]
    val = char.to_i
    number_two += val
    end
    number_two += number_one

    # Calculate the check digit
    check_digit = (10 - (number_two % 10)) % 10

    # Validate
    last_digit = barcode[12].to_i
    check_digit == last_digit
    end

    def convert_card_number_to_barcode(card_number)
    raise "Cannot convert an invalid card number to a barcode" unless is_card_number_valid(card_number)

    barcode = card_number[0..5].gsub(card_number[0..5], "264") + card_number[6..-1]
    check_sum = get_check_sum_from_thirteen_digit_code(barcode)

    # Update the last number with the checksum
    barcode = barcode[0..-2] + check_sum.to_s

    # Post condition validation
    raise "An invalid barcode was created from a card number" unless is_barcode_valid(barcode)

    barcode
    end

    puts convert_card_number_to_barcode(ARGV[0])