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

Trying to figure out why a command line and a perl script using --> my $email_SHA256 = qx(echo $EMAIL_IN | openssl dgst -sha256); yields different results. I am trying to do this without installing the perl module. As you can see in the script, I've REM'd out various attempts at cleaning the data in case it had some carriage returns or Line Feeds.. Any suggestions besides installing the module would be greatly appreciated.

Using the linux command line I enter this:

echo "foobar" | sha256sum aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f - Script output: 0062d3cf2a06daf1d64c931940348cb51c73b28e6fac0dbae65143303286b16d Input File: "130000000640","joe.smith@aol.com" "130000000640","scoobydoo1@gmail.com" "130000000640","foobar" Script: foreach $EMAIL_LIST (@EMAIL_LIST) { my @split_EMAIL_LIST = split(/,/, $EMAIL_LIST); my $USI = $split_EMAIL_LIST[0]; my $EMAIL_IN = $split_EMAIL_LIST[1]; $EMAIL_LENGTH=length($EMAIL_IN) +; #print "Length: $EMAIL_LENGTH\n"; #print "$USI\n"; #my $email_SHA256 = qx(echo -n $EMAIL_IN | openssl dgst -sha256); print "$EMAIL_IN"; chomp($EMAIL_IN); #$EMAIL_IN =~ s/\r\n//; print "$EMAIL_IN"; if($EMAIL_LENGTH > 5) { #echo -n $EMAIL_IN | shasum -a 256 #my $email_SHA256 = qx(echo -n $EMAIL_IN | openssl dgst -sha256); my $email_SHA256 = qx(echo $EMAIL_IN | openssl dgst -sha256); #my $email_SHA256 = exec(`echo -n $EMAIL_IN | sha256sum`); #my $email_SHA256 = exec(echo -n $EMAIL_IN | shasum -a 256); #my $email_SHA256 = exec(printf %s "$EMAIL_IN" | sha256sum); #my $email_SHA256 = qx(printf %s "$EMAIL_IN" | sha256sum); # echo -n "foobar" | openssl dgst -sha256 #my $email_SHA256 = system("sha256sum $EMAIL_IN"); #$email_SHA256 =~ s/stdin//; $email_SHA256 =~ s/\s+\-//; $USI =~ s/"//g; #print "$email_SHA256\n"; my $NEWLINE = $USI . "," . $email_SHA256; #print $NEWLINE; push(@EMAIL_OUT, $NEWLINE); } else { my $NEWLINE = $USI . "," . "No Email Supplied for this USI\n"; print "Length: $EMAIL_LENGTH\n"; print $NEWLINE; push(@EMAIL_NOTVALID, $NEWLINE); } }

Replies are listed 'Best First'.
Re: Perl SHA256
by NERDVANA (Priest) on Feb 13, 2023 at 20:40 UTC
    ...Any suggestions besides installing the module...

    You don't need to install a module because Digest::SHA is a core perl module.

    $ perl -E 'use Digest::SHA "sha256_hex"; say sha256_hex("foobar")' c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2 $ perl -E 'use Digest::SHA "sha256_hex"; say sha256_hex("foobar\n")' aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f

    Anyway, maybe you are asking for advice about shelling out to programs more than advice about calculating SHA digests. You didn't do a very good job at reducing your code to the simplest example, but when I take your code and replace the for loop with $EMAIL_LIST = '"130000000640","foobar"' it works just fine (assuming you are fine with the SHA256 sum including the newline character, which seems pretty wrong to me). So, if your program is broken it is probably something else causing the problem, not the part where you shell out to openssl.

    Here are other random points of advice that apply to what I see here:

    • Do not parse CSV by hand. use Text::CSV for that. Your code is not obeying quote characters and could split a field that contains a comma. You code is also leaving the quote characters attached when passing the email to the shell, which just happens to work because the shell strips off the quote characters before writing it to openssl. Parsing CSV correctly is fiddly enough that you should not try to implement it from scratch.
    • If you need precise control over what is written to an external command, use IPC::Run, or if you have an aversion to non-core modules, use IPC::Open3.
    • If one of your email addresses on input is "foo@$(rm -rf /).com" it will destroy your server. Please consider all the security implications of shelling out with user data.
    • If you really really just want to write user data into a shell command, the only way to semi-safely do it is with a module like ShellQuote::Any. You have no control over what actual shell is being used on someone's system, so escaping things for the shell is a best-guess effort, and using un-trusted external input is still a recipe for disaster.
    • As always, use strict; use warnings; to help you catch problems (or now days use v5.36;) and I recommend Data::Printer to diagnose the contents of your variables, because it can help show newlines and whitespace that you won't see with plain-old "print" statements.
        You don't need to install a module because Digest::SHA is a core perl module.
        $ perl -E 'use Digest::SHA "sha256_hex"; say sha256_hex("foobar")'
        c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2

      Perl also comes with the core utility shasum:

      perl -e 'print "foobar"' | shasum -a 256
      c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
        None of the reply response examples work for emails.. It only works f +or "foobar".. Why are the online links and Linux different? How do +I get perl to give me what both Linux/Online return? https://xorbin.com/tools/sha256-hash-calculator joe.smith@aol.com --> 4d1612632ab95a0dec3d27f521d2b91cabe9e72a6b1ecdb8 +784e1ed6f3a93604 perl -E 'use Digest::SHA "sha256_hex"; say sha256_hex("joe.smith@aol.c +om")' --> 4ea2142392947d467539285b3c6e98f073d9d85910f2a1d535f86a95358 +ab9dd perl -E 'use Digest::SHA "sha256_hex"; say sha256_hex("joe.smith@aol.c +om")' --> 4ea2142392947d467539285b3c6e98f073d9d85910f2a1d535f86a9535 +8ab9dd perl -e 'print "joe.smith@aol.com"' | shasum -a 256 --> 4ea2142392947d +467539285b3c6e98f073d9d85910f2a1d535f86a95358ab9dd - https://codebeautify.org/sha256-hash-generator joe.smith@aol.com --> 4d1612632ab95a0dec3d27f521d2b91cabe9e72a6b1ecdb8 +784e1ed6f3a93604 Linux echo "joe.smith@aol.com" | shasum -a 256 --> d6220b1b3a4a67731d5ca82c1 +01cec2c30069ed674c04576e78322c1fbca1c92 - Linux echo joe.smith@aol.com | shasum -a 256 --> d6220b1b3a4a67731d5ca82c101 +cec2c30069ed674c04576e78322c1fbca1c92 - Linux printf %s "joe.smith@aol.com" | sha256sum --> 4d1612632ab95a0dec3d27f5 +21d2b91cabe9e72a6b1ecdb8784e1ed6f3a93604 - Linux echo -n "joe.smith@aol.com" | openssl dgst -sha256 --> (stdin)= 4d1612 +632ab95a0dec3d27f521d2b91cabe9e72a6b1ecdb8784e1ed6f3a93604
Re: Perl SHA256
by GrandFather (Saint) on Feb 13, 2023 at 20:24 UTC

    Why would you "clean" the plain text? Surely you need to present exactly the same text in both cases? CR and LF are characters too.

    Why don't you want to y=use the module? Yes, even you can use CPAN

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
    A reply falls below the community's threshold of quality. You may see it by logging in.