PHPで16進数値を正しくハッシュするにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/615157

  •  03-07-2019
  •  | 
  •  

質問

一連の16進数バイトがあります。理論的には、最後の20バイトは最初の部分のsha1ハッシュです:

3F F4 E5 25 98 20 52 70 01 63 00 68 00 75 00 79 00 69 00 00 00 74 28 96 10 09 9D C9 01 00 74 A0 D7 DB 0B 9D C9 01 4D 00 79 00 47 00 72 00 6F 00 75 00 70 00 00 00 2F 00 00 00 BD 0D EA 71 BE 0B 25 75 E7 5C 58 20 31 57 F3 9A EF 69 1B FD

このようにPHPでsha1を適用した場合:

echo sha1("3FF4E525982052700163006800750079006900000074289610099DC9010074A0D7DB0B9DC9014D007900470072006F007500700000002F000000");

戻る:

d68ca0839df6e5ac7069cc548d82f249752f3acb

しかし、私はこの値を探しています:

bd0dea71be0b2575e75c58203157f39aef691bfd  

(BD 0D EA 71 BE 0B 25 75 E7 5C 58 20 31 57 F3 9A EF 69 1B FD)

16進値を文字列として扱っているためですか?何をする必要がありますか?

編集:

ここに私が働いている元の情報があります:

ticketBytes
{byte[0x0000003a]}
    [0x00000000]: 0x3f
    [0x00000001]: 0xf4
    [0x00000002]: 0xe5
    [0x00000003]: 0x25
    [0x00000004]: 0x98
    [0x00000005]: 0x20
    [0x00000006]: 0x52
    [0x00000007]: 0x70
    [0x00000008]: 0x01
    [0x00000009]: 0x63
    [0x0000000a]: 0x00
    [0x0000000b]: 0x68
    [0x0000000c]: 0x00
    [0x0000000d]: 0x75
    [0x0000000e]: 0x00
    [0x0000000f]: 0x79
    [0x00000010]: 0x00
    [0x00000011]: 0x69
    [0x00000012]: 0x00
    [0x00000013]: 0x00
    [0x00000014]: 0x00
    [0x00000015]: 0x74
    [0x00000016]: 0x28
    [0x00000017]: 0x96
    [0x00000018]: 0x10
    [0x00000019]: 0x09
    [0x0000001a]: 0x9d
    [0x0000001b]: 0xc9
    [0x0000001c]: 0x01
    [0x0000001d]: 0x00
    [0x0000001e]: 0x74
    [0x0000001f]: 0xa0
    [0x00000020]: 0xd7
    [0x00000021]: 0xdb
    [0x00000022]: 0x0b
    [0x00000023]: 0x9d
    [0x00000024]: 0xc9
    [0x00000025]: 0x01
    [0x00000026]: 0x4d
    [0x00000027]: 0x00
    [0x00000028]: 0x79
    [0x00000029]: 0x00
    [0x0000002a]: 0x47
    [0x0000002b]: 0x00
    [0x0000002c]: 0x72
    [0x0000002d]: 0x00
    [0x0000002e]: 0x6f
    [0x0000002f]: 0x00
    [0x00000030]: 0x75
    [0x00000031]: 0x00
    [0x00000032]: 0x70
    [0x00000033]: 0x00
    [0x00000034]: 0x00
    [0x00000035]: 0x00
    [0x00000036]: 0x2f
    [0x00000037]: 0x00
    [0x00000038]: 0x00
    [0x00000039]: 0x00

hashed
{byte[0x00000014]}
    [0x00000000]: 0xbd
    [0x00000001]: 0x0d
    [0x00000002]: 0xea
    [0x00000003]: 0x71
    [0x00000004]: 0xbe
    [0x00000005]: 0x0b
    [0x00000006]: 0x25
    [0x00000007]: 0x75
    [0x00000008]: 0xe7
    [0x00000009]: 0x5c
    [0x0000000a]: 0x58
    [0x0000000b]: 0x20
    [0x0000000c]: 0x31
    [0x0000000d]: 0x57
    [0x0000000e]: 0xf3
    [0x0000000f]: 0x9a
    [0x00000010]: 0xef
    [0x00000011]: 0x69
    [0x00000012]: 0x1b
    [0x00000013]: 0xfd
役に立ちましたか?

解決

ここで何かが非常に間違っています。 SHA1ダイジェストは160ビットであり、20桁の16進数で表されます。 40文字。あなたが期待している値は32文字です。これはSHA1ダイジェストではないことを意味します-または私がまだ理解していない何かが欠けています。

他のヒント

残念ながら、これは正しい値を提供しませんが、正しい方向を指し示すかもしれません。どちらにしても、ハッシュする前に実際に16進コードをバイナリ文字列に変換することをお勧めします。このように:

$str = "3F F4 E5 25 98 20 52 70 01 63 00 68 00 75 00 79 00 69 00 00 00 74 28 96 10 09 9D C9 01 00 74 A0 D7 DB 0B 9D C9 01 4D 00 79 00 47 00 72 00 6F 00 75 00 70 00 00 00 2F 00 00 00";

// Create an array where each entry represents a single byte in hex
$arr = explode(" ", $str);
// Convert the hex to decimal
$arr = array_map("hexdec", $arr);
// Convert the decimal number into the corresponding ASCII character
$arr = array_map("chr", $arr);

// Implode the array into a string, and hash the result
$result = sha1(implode($arr));

echo $result."\n";

結果はfa3ebc158305d09443b4315d35c0eee5aa72daefであり、これもvartecsコードが生成するものです。こことバルテックで使用されているアプローチは、私たちが知っている事実に基づいてそれを行うための最も論理的な方法であるため、正しい参照がどのように計算されるのかわからないという側面があると思います。

$hexes = "3F F4 E5 25 98 20 52 70 01 63 00 68 00 75 00 79 00 69 00 00 00 74 28 96 10 09 9D C9 01 00 74 A0 D7 DB 0B 9D C9 01 4D 00 79 00 47 00 72 00 6F 00 75 00 70 00 00 00 2F 00 00 00";
$hexes = split(' ',$hexes);
$hexes = array_map('hexdec',$hexes);
$hexes = call_user_func_array('pack',array_merge(array('C*'),$hexes));
echo sha1($hexes);

ところで。別の形式で渡すことで同じことを実現できます。

$hexes = "\x3F\xF4\xE5\x25\x98\x20\x52\x70\x01\x63\x00\x68\x00\x75\x00\x79\x00\x69\x00\x00\x00\x74\x28\x96\x10\x09\x9D\xC9\x01\x00\x74\xA0\xD7\xDB\x0B\x9D\xC9\x01\x4D\x00\x79\x00\x47\x00\x72\x00\x6F\x00\x75\x00\x70\x00\x00\x00\x2F\x00\x00\x00";
echo sha1($hexes);

pack 関数を使用して、16進文字列をバイナリ:

$bin = pack('H*', preg_replace('/[^0-9a-fA-F]+/', '', $hex));

chr()を使用して文字列に変換します。.

$string = "3f ........"
$c = split(' ',$string);
$string2 = '';
foreach( $c as $char )
{
 $string2 .= chr(hexdec($c));
}

echo sha1($string2);

これは動作します:

function strToHex($string)
{
    $hex='';
    for ($i=0; $i < strlen($string); $i++)
    {
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}
echo sha1(strToHex("3FF4E525982052700163006800750079006900000074289610099DC9010074A0D7DB0B9DC9014D007900470072006F007500700000002F000000"));

>> 5b102a482247fef726843f214f8a81b1627bb634

sha1()ではなく、検証キーでhash_hmac()を使用する必要があることが判明しました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top