http://www.perlmonks.org?node_id=611112

js1 has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

Is there a straightforward way of converting a string of chars and numerics such as smpl95, smpd9, fuj324 etc.... to a numeric value.

The numeric value could be generated any way, just as long as it returned a number. So for example:

sub str2num{ return hash($str); } $str='smpl95'; $num=str2num($str);

A given string will always return the same value on each call. I'm not worried about being able to reverse the number after, into the same string though.

Cheers,

js1.

Replies are listed 'Best First'.
Re: convert string of chars and numerics to a numeric value
by johngg (Canon) on Apr 20, 2007 at 11:11 UTC
    One way to do it would be to split the string into individual characters and sum the ord values for each character. The problem with that is it's easy to get the same answer for different strings. Perhaps you could concatenate the ord values into a string of numbers. This would have the advantage that you could reconstruct the original string from the numbers.

    use strict; use warnings; my @strs = qw{smpl95 smpd9 fuj324}; foreach my $str ( @strs ) { print qq{Original: $str\n}; my $numStr = there($str); print qq{Numified: $numStr\n}; my $decoded = backAgain($numStr); print qq{ Decoded: $decoded\n}; print q{-} x 25, qq{\n}; } sub there { my $str = shift; my $numStr; $numStr .= sprintf q{%03d}, ord for split m{}, $str; return $numStr; } sub backAgain { my $numStr = shift; (my $str = $numStr) =~ s{(...)}{chr $1}eg; return $str; }

    Here's the output.

    Original: smpl95 Numified: 115109112108057053 Decoded: smpl95 ------------------------- Original: smpd9 Numified: 115109112100057 Decoded: smpd9 ------------------------- Original: fuj324 Numified: 102117106051050052 Decoded: fuj324 -------------------------

    I don't know if this is anywhere near what you are looking for. Perhaps you could clarify you question?

    Cheers,

    JohnGG

      John,

      Thanks. That's more or less what I was after. In the line below, could you explain how ord for split m{} works please? I haven't seen that syntax before. Very cool though!

      $numStr .= sprintf q{%03d}, ord for split m{}, $str;
        I'm glad my guess was along the right lines. Perhaps if I expand the code it will become clearer what is going on. The main points are: split will break a string into individual characters if given an empty pattern as it's delimiter; ord is one of those built-ins that operates by default on $_; I am using the for (synonym for foreach) as a statement modifier rather than writing an explicit loop. So, in English, concatenate $newStr with the ordinal value, formatted to three digits with leading-zero padding, of each character in the string. These characters are passed one at a time in the variable $_ to the .= statement by the for statement modifier from the list that results from the split statement.

        Here's the code expanded and using temporary variables.

        foreach my $char ( split m{}, $str ) { my $ordVal = ord $char; my $fixedWidthOrdVal = sprintf q{%03d}, $ordVal; $numStr .= $fixedWidthOrdVal; }

        I hope that has explained the code satisfactorily but, if not, please ask.

        Cheers,

        JohnGG

Re: convert string of chars and numerics to a numeric value
by GrandFather (Saint) on Apr 20, 2007 at 10:07 UTC

    How do you get from 'smpl95' to 342 (and similarly for your other example values)? If that is not an appropriate mapping,perhaps you could provide a few clearer examples. It would also help a lot if you provided a little more information about what you are trying to achieve and the code that you have tried so far.

    Update: note that making a significant change to your node contents without indicating that it has been updated is generally frowned on. Nice to see some code has been added and the question clarified a little, but please show that as an update.


    DWIM is Perl's answer to Gödel
Re: convert string of chars and numerics to a numeric value
by andye (Curate) on Apr 20, 2007 at 10:15 UTC
    Hiya,

    You want to keep the numbers and remove the letters?

    Or you want to convert the letters to their ascii character codes? Doing the same with the numbers, or not?

    Or something else?

    Best wishes, andye

Re: convert string of chars and numerics to a numeric value
by swampyankee (Parson) on Apr 23, 2007 at 03:21 UTC

    If you want a consistent value given an arbitrary string, I would suggest some sort of hashing algorithm, such as that embodied in the *ix sum program. Treating the string as a base-36 number is another possibility. For this you could use the Math::base36 module.

    emc

    Insisting on perfect safety is for people who don't have the balls to live in the real world.

    —Mary Shafer, NASA Dryden Flight Research Center