简体   繁体   中英

Javascript Sha256 vs PHP Sha256: Line breaks create different hash?

I am getting two different hash values when line breaks are added.

On this site http://www.xorbin.com/tools/sha256-hash-calculator there is a JavaScript Sha256 hash generator.

When I run a hash on "onetwo" I get:

25b6746d5172ed6352966a013d93ac846e1110d5a25e8f183b5931f4688842a1

When I use PHP

echo hash('sha256', 'onetwo');

I get:

25b6746d5172ed6352966a013d93ac846e1110d5a25e8f183b5931f4688842a1

But when I run a hash from the URL that includes a line break (return) like:

'one
two'

I get:

21066d108d5319ecb5a1fc4454f42ef22fc5f1c7df49c31d90294950e0ea8b2c

But when I use PHP I get:

29a776bb35efe730dabb1b1d3ad74dbf80cc3e9009e168241798ea73adca3dcf

Can any one point out why this is so? Why does adding line breaks give different results?

Here is my PHP/HTML code as you will see I am using a form and submitting the data to be hashed.

<!DOCTYPE HTML>
<html>
  <head>
    <title>Sha256 Hash</title>
  </head>
  <body>
    <div style="float: left;">
      Start here and insert text below to be hashed.<br />
      <form name="submit hash" action="" method="POST">
        <textarea name="text" style="border: thin solid #000; width: 500px; padding: 10px; height: 500px;"><? if($_SERVER['REQUEST_METHOD'] == 'POST') echo $_POST['text']; ?></textarea>
        <br style="clear: both;" />
        <input type="submit" name="submit" value="submit" />
      </form>
    </div>
    <? if($_SERVER['REQUEST_METHOD'] == 'POST'): ?>
    <div style="border: thin solid #000; margin: 10px; padding: 10px; float: left;">
      <br />sha256:&nbsp;&nbsp;<b><?= hash('sha256',$_POST['text']); ?></b><br />
    </div>
    <? endif; ?>
  </body>
</html>

@mrjoltcola is right.

When getting the value from the textarea the new lines are \\r\\n (CRLF).

You can validate this in your php code by printing the url encoded version of the string that you read like that:

var_dump(urlencode($_POST['text']));

This will print string(12) "one%0D%0Atwo" if you enter

one
two

where %0D is the html code for carriage return and %0A for line feed as you can see here .

Now to get the same hash as in the javascript version you have to remove the carriage return. You can do that it in php like that:

$string_to_be_hashed = preg_replace( "/\r\n/", "\n", $_POST['text'] );

Then, if you hash the $string_to_be_hashed you will get the expected result.

In the javascript version this happens also internally. If you check the hash256 source code there is a Utf8Encode(string) function where the first line is string = string.replace(/\\r\\n/g,"\\n"); which is essentialy the same.

I would expect it is the difference between carriage return and line feeds ( \\r\\n vs \\n )

Your PHP inline test string probably only has \\n

The web one probably has \\r\\n

Secondly, these are considered part of the content. Hashing it doesn't ignore it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM