Encode as alphanumeric

T

Trans

Hi,

I need to take an arbitrary byte string and encode it as alphanumeric
(and decode it back again). Any pointers on a easy way to do this?

Thanks,
T.
 
S

Sean O'Halpin

Hi,

I need to take an arbitrary byte string and encode it as alphanumeric
(and decode it back again). Any pointers on a easy way to do this?

Thanks,
T.
Here's one way:

require 'base64'

str = Base64.encode64('\0\1')
# => "XDBcMQ==\n"
Base64.decode64(str)
# => "\\0\\1"

HTH
Sean
 
M

MenTaLguY

I need to take an arbitrary byte string and encode it as alphanumeric
(and decode it back again). Any pointers on a easy way to do this?

What sort of encoding do you have in mind? Hexadecimal? Base64?

-mental
 
T

Trans

What sort of encoding do you have in mind? Hexadecimal? Base64?

I'm using a two-way encryption algorithm to create a registration key.
The encryption algorithm produces an arbitrary byte string. I need to
encode that into something I can give to a end-user, ie. an
alphanumeric string.

Base64 is close but not quite [a-zA-Z0-9].

T.
 
T

t3ch.dude

What sort of encoding do you have in mind?  Hexadecimal?  Base64?

I'm using a two-way encryption algorithm to create a registration key.
The encryption algorithm produces an arbitrary byte string. I need to
encode that into something I can give to a end-user, ie. an
alphanumeric string.

Base64 is close but not quite [a-zA-Z0-9].

T.

How about a proper subset [a-f0-9] ?

irb(main):001:0> readable = "\0\1ALf\3=".unpack('H*')
=> ["0001414c66033d"]
irb(main):002:0> original = readable.pack('H*')
=> "\000\001ALf\003="

-T3ch.dude
 
M

MenTaLguY

What sort of encoding do you have in mind? Hexadecimal? Base64?

I'm using a two-way encryption algorithm to create a registration key.
The encryption algorithm produces an arbitrary byte string. I need to
encode that into something I can give to a end-user, ie. an
alphanumeric string.

Base64 is close but not quite [a-zA-Z0-9].

I see. Base 62 then? The most direct way is to get things as a bignum
and then convert bases using divmod.

DIGIT_CHARS = ["0".."9", "a".."z", "A".."Z"].map { |r| r.to_a }.flatten
BASE = DIGIT_CHARS.size
DIGIT_VALUES = Hash[*(0...BASE).map { |i| [ DIGIT_CHARS, i ] }.flatten]

def convert_base(digits, from_base, to_base)
bignum = 0
digits.each { |digit| bignum = bignum * from_base + digit }
converted = []
until bignum.zero?
bignum, digit = bignum.divmod to_base
converted.push digit
end
converted.reverse
end

def encode(byte_string)
convert_base(byte_string.unpack("C*"), 256, BASE).map { |d|
DIGIT_CHARS[d]
}.join('')
end

def decode(encoded)
convert_base(encoded.split('').map { |c|
DIGIT_VALUES[c]
}, BASE, 256).pack("C*")
end

There are more efficient ways of accomplishing this, of course.

Note that with this implementation, you'd probably want to zero-fill to
whatever standard number of characters and bytes you're using, and of
course a key of all zeroes will result in an empty string.

As a usability thing, I'd also suggest non-uniformly adding dashes or
spaces in standard places to the encoded form, to help users visually
"chunk" the keys if they ever might have to type them in.

-mental
 
F

F. Senault

Le 26 mars 2008 à 21:44, Trans a écrit :
I'm using a two-way encryption algorithm to create a registration key.
The encryption algorithm produces an arbitrary byte string. I need to
encode that into something I can give to a end-user, ie. an
alphanumeric string.

How long is your key ? If it's relatively short, you could use the
mechanism described in the RFC 1760 (S/KEY), which shows a method to
converts a number into a group of 6 small words.

| 0: 3D8B BA84 B4A5 E7E2
| 1: 5F2A 00BE DCF1 E6AD

Becomes :

| 0: SOP BOUT JESS COED BRAG TURF
| 1: BRIM AWAY OR MELT IRE BESS

(It's used in the OPIE implementations on some *nix systems ; on
FreeBSD, I made the above with azertyuiop as a passphrase and :)

| 22:46 fred@balvenie:~> opiekey -x -n 5 1 zb78774
| 22:46 fred@balvenie:~> opiekey -n 5 1 zb78774

Fred
 
T

Trans

irb(main):001:0> readable = "\0\1ALf\3=".unpack('H*')
=> ["0001414c66033d"]
irb(main):002:0> original = readable.pack('H*')
=> "\000\001ALf\003="

Concise, but the resulting string is longer than I would prefer.

Thanks though,
T.
 
T

Trans

I'm using a two-way encryption algorithm to create a registration key.
The encryption algorithm produces an arbitrary byte string. I need to
encode that into something I can give to a end-user, ie. an
alphanumeric string.
Base64 is close but not quite [a-zA-Z0-9].

I see. Base 62 then? The most direct way is to get things as a bignum
and then convert bases using divmod.

DIGIT_CHARS = ["0".."9", "a".."z", "A".."Z"].map { |r| r.to_a }.flatten
BASE = DIGIT_CHARS.size
DIGIT_VALUES = Hash[*(0...BASE).map { |i| [ DIGIT_CHARS, i ] }.flatten]

def convert_base(digits, from_base, to_base)
bignum = 0
digits.each { |digit| bignum = bignum * from_base + digit }
converted = []
until bignum.zero?
bignum, digit = bignum.divmod to_base
converted.push digit
end
converted.reverse
end

def encode(byte_string)
convert_base(byte_string.unpack("C*"), 256, BASE).map { |d|
DIGIT_CHARS[d]
}.join('')
end

def decode(encoded)
convert_base(encoded.split('').map { |c|
DIGIT_VALUES[c]
}, BASE, 256).pack("C*")
end

There are more efficient ways of accomplishing this, of course.


This is perfect for my needs. Thank you.
Note that with this implementation, you'd probably want to zero-fill to
whatever standard number of characters and bytes you're using, and of
course a key of all zeroes will result in an empty string.

As a usability thing, I'd also suggest non-uniformly adding dashes or
spaces in standard places to the encoded form, to help users visually
"chunk" the keys if they ever might have to type them in.

Cool.

Thanks again mental,
T.
 
A

ara.t.howard

I see. Base 62 then?

you know that would really be quite useful - base64 has the ultra
annoying property that it includes '/' which breaks urls unless
encoded/decoded.

cheers.

-a
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top