Skip to content

Instantly share code, notes, and snippets.

@amiralles
Last active October 2, 2018 14:39
Show Gist options
  • Save amiralles/e3ab5fcb0cb652c9d39998353255c3bf to your computer and use it in GitHub Desktop.
Save amiralles/e3ab5fcb0cb652c9d39998353255c3bf to your computer and use it in GitHub Desktop.
Encode/Decode cell addresses into integers using ruby
#!/usr/local/bin/ruby -w
# Bit masks
MASKA = 0XFFFF
MASKB = 0XFFFFFFFF
MASKR = 0XFFFFFFFFFFFFFFFF
def letter? ch; ch =~ /[a-zA-Z]/ end
def number? ch; ch =~ /[0-9]/ end
# Returns the two letters that conforms
# the column name, or one letter and a
# null char if the lenght of the column
# name is 1.
# So, the result is always twoc chars [a,b].
def split col
a = col[0].ord
b = '_'.ord
b = col[1].ord if col.length == 2
[a, b]
end
# Parses a cell address and returns:
# [true, col, row] is the address is valid, or
# [false, nil, nil] if the parse failed.
def parse addr
colsize = 0
colsize += 1 if letter? addr[0]
colsize += 1 if letter? addr[1]
return [false, nil, nil] if colsize == 0
col = addr[0..colsize-1]
row = addr[colsize..-1].to_i
[true, col, row]
end
# Returns an encoded value that represents a
# cell address or -1 if arguments are invalid.
# Valid column values are [a..zz] and valid
# row values are [1..65535].
def encode addr
ok, col, row = parse(addr)
return -1 unless ok
a, b = split(col)
encoded = 0
encoded |= (a << 8)
encoded |= (b << 16)
encoded |= (row << 32)
encoded
end
# Decodes and encoded cell address.
# (See encode method.)
def decode encoded
a = (encoded & MASKA) >> 8
b = (encoded & MASKB) >> 16
r = (encoded & MASKR) >> 32
return "#{a.chr}#{r}" if b.chr == '_'
return "#{a.chr}#{b.chr}#{r}"
end
def main
addr1, addr2 = "A1", "AZ65535"
a1 = encode addr1
az65535 = encode addr2
puts "#{addr1} encoded: #{a1}"
puts "#{addr2} encoded: #{az65535}"
puts ""
puts "#{a1} decoded: #{decode(a1)}"
puts "#{az65535} decoded: #{decode(az65535)}"
end
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment