class ObjectIdEncoder attr_accessor :id def initialize(id) @id = id.to_a raise "invalid ID!" unless @id.size == 12 end def encode result = [] 4.times do |i| base = i * 3 tmp = @id[base + 2] tmp |= @id[base + 1] << 8 tmp |= @id[base] << 16 result << TABLE[tmp >> 18] result << TABLE[(tmp >> 12) & 0x3f] result << TABLE[(tmp >> 6) & 0x3f] result << TABLE[tmp & 0x3f] end result.join end end class ObjectIdDecoder attr_accessor :str_id def initialize(str_id) raise "invalid ID!" unless str_id.size == 16 @str_id = str_id end def decode result = [] 4.times do |i| base = i * 4 tmp = TABLE.index(@str_id[base + 3]) tmp |= TABLE.index(@str_id[base + 2]) << 6 tmp |= TABLE.index(@str_id[base + 1]) << 12 tmp |= TABLE.index(@str_id[base]) << 18 result << (tmp >> 16) result << ((tmp >> 8) & 0xFF) result << (tmp & 0xFF) end str_id = result.map { |x| "%.2x" % x }.join BSON::ObjectId(str_id) end end