Encode as alphanumeric

Discussion in 'Ruby' started by Trans, Mar 26, 2008.

  1. Trans

    Trans Guest

    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.
    Trans, Mar 26, 2008
    #1
    1. Advertising

  2. On Wed, Mar 26, 2008 at 8:13 PM, Trans <> wrote:
    > 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
    Sean O'Halpin, Mar 26, 2008
    #2
    1. Advertising

  3. Trans

    MenTaLguY Guest

    On Thu, 27 Mar 2008 05:13:23 +0900, Trans <> wrote:
    > 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
    MenTaLguY, Mar 26, 2008
    #3
  4. Trans

    Trans Guest

    On Mar 26, 4:27 pm, MenTaLguY <> wrote:
    > On Thu, 27 Mar 2008 05:13:23 +0900, Trans <> wrote:
    > > 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?


    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.
    Trans, Mar 26, 2008
    #4
  5. Trans

    t3ch.dude Guest

    On Mar 26, 4:44 pm, Trans <> wrote:
    > On Mar 26, 4:27 pm, MenTaLguY <> wrote:
    >
    > > On Thu, 27 Mar 2008 05:13:23 +0900, Trans <> wrote:
    > > > 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?

    >
    > 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
    t3ch.dude, Mar 26, 2008
    #5
  6. Trans

    MenTaLguY Guest

    On Thu, 27 Mar 2008 05:44:12 +0900, Trans <> wrote:
    > On Mar 26, 4:27 pm, MenTaLguY <> wrote:
    >> On Thu, 27 Mar 2008 05:13:23 +0900, Trans <> wrote:
    >> > 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?

    >
    > 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
    MenTaLguY, Mar 26, 2008
    #6
  7. Trans

    F. Senault Guest

    Le 26 mars 2008 à 21:44, Trans a écrit :

    > On Mar 26, 4:27 pm, MenTaLguY <> wrote:
    >> On Thu, 27 Mar 2008 05:13:23 +0900, Trans <> wrote:
    >>> 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?

    >
    > 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
    --
    Error: No applicable methods for #<STANDARD-GENERIC-FUNCTION CLOS:SLOT-
    VALUE-USING-CLASS 506F939A> with args (#<BUILT-IN-CLASS NULL 5072054C>
    NIL ADDRESS) Sorry, what is this "wife" thing? Is it related to the
    rumoured existence of something called "life" ? (Arvid Grøtting, SDM)
    F. Senault, Mar 26, 2008
    #7
  8. Trans

    Trans Guest

    On Mar 26, 5:24 pm, "t3ch.dude" <> wrote:

    > 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.
    Trans, Mar 26, 2008
    #8
  9. Trans

    Trans Guest

    On Mar 26, 5:33 pm, MenTaLguY <> wrote:
    > On Thu, 27 Mar 2008 05:44:12 +0900, Trans <> wrote:
    > > On Mar 26, 4:27 pm, MenTaLguY <> wrote:
    > >> On Thu, 27 Mar 2008 05:13:23 +0900, Trans <> wrote:
    > >> > 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?

    >
    > > 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.
    Trans, Mar 26, 2008
    #9
  10. Trans

    ara.t.howard Guest

    On Mar 26, 2008, at 3:33 PM, MenTaLguY wrote:
    > 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
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
    ara.t.howard, Mar 27, 2008
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. VB Programmer

    Check if var is alphanumeric?

    VB Programmer, Nov 16, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    572
    bruce barker
    Nov 16, 2004
  2. Steven J Sobol
    Replies:
    8
    Views:
    5,664
    Thomas Weidenfeller
    Apr 30, 2004
  3. Paul
    Replies:
    1
    Views:
    13,181
    Rogan Dawes
    Sep 14, 2004
  4. Alphanumeric font

    , Dec 17, 2004, in forum: Java
    Replies:
    2
    Views:
    2,174
    Geli J. Crick
    Dec 17, 2004
  5. enrique
    Replies:
    2
    Views:
    554
Loading...

Share This Page