Mapping characters in a string

A

Alfred von Campe

I must have a brain cramp today, because I can not figure out an
elegant way to do the following. I have a 16 byte, binary MD5 digest
(generated with Digest::MD5) in one scalar, and another scalar
containing exactly 256 printable characters. I want to create a
printable version of the MD5 digest by using the bytes of the digest
as an index into the string of printable characters. I can do this in
a loop one byte at a time, but there must be a solution using map
and/or pack/unpack to do this more elegantly. Any ideas?

Alfred
 
U

Uri Guttman

AvC> I must have a brain cramp today, because I can not figure out an
AvC> elegant way to do the following. I have a 16 byte, binary MD5 digest
AvC> (generated with Digest::MD5) in one scalar, and another scalar
AvC> containing exactly 256 printable characters. I want to create a
AvC> printable version of the MD5 digest by using the bytes of the digest
AvC> as an index into the string of printable characters. I can do this in
AvC> a loop one byte at a time, but there must be a solution using map
AvC> and/or pack/unpack to do this more elegantly. Any ideas?

slice to the (double) rescue!!

<untested>

my $encoded_md5 = join( '', (split //, $md5_map)[ split //, $md5_digest ] ) ;

<aside to lame flamer>
oh, borland, where is thy limp flame now? any answers from you?
typical flame but no help.
</aside to lame flamer>

uri
 
J

John W. Krahn

Alfred said:
I must have a brain cramp today, because I can not figure out an
elegant way to do the following. I have a 16 byte, binary MD5 digest
(generated with Digest::MD5) in one scalar, and another scalar
containing exactly 256 printable characters. I want to create a
printable version of the MD5 digest by using the bytes of the digest
as an index into the string of printable characters. I can do this in
a loop one byte at a time, but there must be a solution using map
and/or pack/unpack to do this more elegantly. Any ideas?

Did you try Digest::MD5::md5_hex() or Digest::MD5::md5_base64() for a
printable version?


John
 
A

Anno Siegel

Uri Guttman said:
AvC> I must have a brain cramp today, because I can not figure out an
AvC> elegant way to do the following. I have a 16 byte, binary MD5 digest
AvC> (generated with Digest::MD5) in one scalar, and another scalar
AvC> containing exactly 256 printable characters. I want to create a
AvC> printable version of the MD5 digest by using the bytes of the digest
AvC> as an index into the string of printable characters. I can do this in
AvC> a loop one byte at a time, but there must be a solution using map
AvC> and/or pack/unpack to do this more elegantly. Any ideas?

slice to the (double) rescue!!

<untested>

my $encoded_md5 = join( '', (split //, $md5_map)[ split //, $md5_digest ] ) ;

There's an ord() missing.

(split //, $md5_map)[ map ord, split //, $md5_digest ] ) ;


Alternatively:

$_ = $md5_digest;
eval "tr/\0-\xff/$md5_map/";
$encoded_md5 = $_;

Extra points for why the dreaded string-eval is required here (and
absolutely harmless). No, not you, Uri :)
<aside to lame flamer>
oh, borland, where is thy limp flame now? any answers from you?
typical flame but no help.
</aside to lame flamer>

Oh, come on, don't nettle her. She may still come around.

Anno
 
A

Alfred von Campe

Uri Guttman said:
slice to the (double) rescue!!

<untested>

my $encoded_md5 = join( '', (split //, $md5_map)[ split //, $md5_digest ] ) ;

Close. I get lots of errors like this:

Argument "^[" isn't numeric in list slice at ./encode.pl line 16.

And then I get a 16 byte string where all the characters are equal to
the first character in the mapping string (position 0), which makes
sense. Including a map to ord as shown in the next post solved the
problem.

Alfred
 
A

Alfred von Campe

Abigail said:
Untested:

use bytes; # Just in case.

$digest = "........"; # 16 bytes.
$chars = "........"; # 256 chars.

my $str = join "" => (split // => $chars) [map {ord} split // => $digest];

Brilliant! This works just as is. BTW, the "use bytes;" is not needed.

Many thanks,
Alfred
 
A

Alfred von Campe

John W. Krahn said:
Did you try Digest::MD5::md5_hex() or Digest::MD5::md5_base64() for a
printable version?

Yes, but that doesn't solve my problem. I need to map it to a
specific sequence of characters to implement an existing algorithm.

Alfred
 
U

Uri Guttman

AS> Uri Guttman said:
<untested>

my $encoded_md5 = join( '', (split //, $md5_map)[ split //, $md5_digest ] ) ;

AS> There's an ord() missing.

AS> (split //, $md5_map)[ map ord, split //, $md5_digest ] ) ;

yeah, saw abigail's solution which was the same but for the needed
ord. as i said, <untested> :)


AS> Alternatively:

AS> $_ = $md5_digest;
AS> eval "tr/\0-\xff/$md5_map/";
AS> $encoded_md5 = $_;

AS> Extra points for why the dreaded string-eval is required here (and
AS> absolutely harmless). No, not you, Uri :)


AS> Oh, come on, don't nettle her. She may still come around.

strident (f)lamer types like that want to feel superior but don't have
the proper skills. the challenge to them to help others almost always
shuts them up.

uri
 
U

Uri Guttman

AvC> Yes, but that doesn't solve my problem. I need to map it to a
AvC> specific sequence of characters to implement an existing algorithm.

you should have stated that with the original problem. note that you got
two answers (abigail's any my slightly incorrect one) but do you
understand how they work? please don't cut and paste them and not know
why they work. that would be antithetical to this group's goals

uri
 
A

Alfred von Campe

Uri Guttman said:
you should have stated that with the original problem. note that you got
two answers (abigail's any my slightly incorrect one) but do you
understand how they work? please don't cut and paste them and not know
why they work. that would be antithetical to this group's goals

Mea culpa (on the original problem statement). I did use Abigail's
solution and modified it slightly. I didn't understand it at first,
but I do now (after disecting it from right to left).

Thanks to all for your help,
Alfred
 
U

Uri Guttman

AvC> Mea culpa (on the original problem statement). I did use Abigail's
AvC> solution and modified it slightly. I didn't understand it at first,
AvC> but I do now (after disecting it from right to left).

then show us your modifications. anything generally interesting? or was
is just to your taste?

uri
 
A

Anno Siegel

Uri Guttman said:
AvC> Mea culpa (on the original problem statement). I did use Abigail's
AvC> solution and modified it slightly. I didn't understand it at first,
AvC> but I do now (after disecting it from right to left).

then show us your modifications. anything generally interesting? or was
is just to your taste?

If efficiency is any concern, the tr/// solution I posted is faster
by a factor of 7. That is calling tr/// through string-eval each time.
If the tr/// is precompiled, it is about 130 times as fast. So there's
room for improvement, if needed.

Anno
 
A

Alfred von Campe

Uri Guttman said:
then show us your modifications. anything generally interesting? or was
is just to your taste?

Nothing earth shattering. Just cosmetic things, and I put it all in a subroutine.

Alfred
 

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

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,735
Latest member
HikmatRamazanov

Latest Threads

Top