Tuesday, May 28, 2013

A Simple Binascii Module in Ruby and Lua

Whenever I'm working with binary data in Python, I inevitably find myself using the binascii module. The methods hexlify and unhexlify make it extremely easy to convert between binary data and the corresponding hexadecimal string.

I thought it would be fun to write a subset of Python's binascii module in Ruby and Lua.

binascii.rb


module Binascii
  def self.hexlify(s)
    a = []
    s.each_byte do |b|
      a << sprintf('%02X', b)
    end
    a.join
  end

  def self.unhexlify(s)
    a = s.split
    return a.pack('H*')
  end
end

binascii_example.rb


#!/usr/bin/env ruby

require 'binascii'

puts Binascii.hexlify('123')
puts Binascii.unhexlify('313233')

binascii_example.rb output


313233
123

binascii.lua


-- module setup
local modname = ...
local M = {}
_G[modname] = M
package.loaded[modname] = M

-- import section
local error = error
local string = string
local table = table
local tonumber = tonumber

-- no more external access after this point
setfenv(1, M)

---
-- Converts a string of bytes to a hexadecimal string
function hexlify(s)
    local a = {}
    for i=1,#s do
        local c = string.sub(s,i,i)
        local byte = string.byte(c)
        table.insert(a, string.format('%02X', byte))
    end
    return table.concat(a)
end

---
-- Converts a hexadecimal string to a string of bytes
function unhexlify(s)
    if #s % 2 ~= 0 then
        error('unhexlify: hexstring must contain even number of digits')
    end
    local a = {}
    for i=1,#s,2 do
        local hs = string.sub(s, i, i+1)
        local code = tonumber(hs, 16)
        if not code then
            error(string.format("unhexlify: '%s' is not avalid hex number", hs))
        end
        table.insert(a, string.char(code))
    end
    return table.concat(a)
end

binascii_example.lua


#!/usr/bin/env lua

local binascii = require 'binascii'

print(binascii.hexlify('123'))
print(binascii.unhexlify('313233'))

binascii_example.lua output


313233
123

No comments:

Post a Comment