Hash: immutable hash over array

with sorted keys, but arrays stay unsorted
This commit is contained in:
2026-09-18 18:36:40 +09:00
parent 2bb405d741
commit 0b057864ae
3 changed files with 96 additions and 0 deletions
@@ -421,6 +421,71 @@ final class CoreLibsCreateHashTest extends TestCase
'hash hmac valid' 'hash hmac valid'
); );
} }
// MARK: generateImmutableHashForArray
/**
* Data provider for testGenerateImmutableHashForArray.
*
* @return array
*/
public function generateImmutableHashForArrayProvider(): array
{
return [
'Empty array' => [
[],
'064f01fe',
],
'Simple array' => [
['key' => 'value'],
'78f40899',
],
'flat array a' => [
[0, 1, 'b', 'c', 'a'],
'ccec0f5b',
],
'flat array b' => [
['b', 'c', 'a', 1, 0],
'c6040f5b',
],
'key array a' => [
['A' => 0, 'F' => 1, 'C' => 'b', 'K' => 'c', 'B' => 'a'],
'01f11355',
],
'key array b' => [
['A' => 0, 'B' => 'a', 'C' => 'b', 'F' => 1, 'K' => 'c'],
'01f11355',
],
'complex nested array' => [
[
'level1' => [
'level2' => [
'level3' => 'value'
]
]
],
'd8de1565',
]
];
}
/**
* Test for generating an immutable hash from an array.
*
* @covers ::generateImmutableHashForArray
* @dataProvider generateImmutableHashForArrayProvider
* @testdox generate immutable hash for array with result $expected [$_dataName]
*
* @param array<mixed> $input
* @param string $expected
*/
public function testGenerateImmutableHashForArray(array $input, string $expected): void
{
$this->assertEquals(
$expected,
\CoreLibs\Create\Hash::generateImmutableHashForArray($input)
);
}
} }
// __END__ // __END__
+13
View File
@@ -103,6 +103,19 @@ foreach ($hash_types as $hash_type) {
// print "UNIQU ID SHORT : " . Hash::__uniqId() . "<br>"; // print "UNIQU ID SHORT : " . Hash::__uniqId() . "<br>";
// print "UNIQU ID LONG : " . Hash::__uniqIdLong() . "<br>"; // print "UNIQU ID LONG : " . Hash::__uniqIdLong() . "<br>";
$tests = [
// array diff
[0, 1, 'b', 'c', 'a'],
['b', 'c', 'a', 1, 0],
// key set arrays DO NOT diff
['A' => 0, 'F' => 1, 'C' => 'b', 'K' => 'c', 'B' => 'a'],
['A' => 0, 'B' => 'a', 'C' => 'b', 'F' => 1, 'K' => 'c'],
];
foreach ($tests as $test) {
print "IMMUTABLE HASH FOR ARRAY: " . Hash::generateImmutableHashForArray($test) . "<br>";
print "SERIALIZED HASH FOR ARRAY: " . hash(Hash::DEFAULT_HASH, serialize($test)) . "<br>";
}
print "</body></html>"; print "</body></html>";
// __END__ // __END__
+18
View File
@@ -8,6 +8,8 @@ declare(strict_types=1);
namespace CoreLibs\Create; namespace CoreLibs\Create;
use CoreLibs\Combined\ArrayHandler;
class Hash class Hash
{ {
/** @var string default short hash -> deprecated use STANDARD_HASH_SHORT */ /** @var string default short hash -> deprecated use STANDARD_HASH_SHORT */
@@ -210,6 +212,22 @@ class Hash
{ {
return self::hash($string, self::STANDARD_HASH); return self::hash($string, self::STANDARD_HASH);
} }
/**
* generate a hash over any array data
*
* @param array<mixed> $data
* @return string
*/
public static function generateImmutableHashForArray(array $data): string
{
// Create a sorted copy to ensure consistent hashing
// Generate hash using serialize for better accuracy
return hash(
self::DEFAULT_HASH,
serialize(ArrayHandler::createSortedArrayByKey($data))
);
}
} }
// __END__ // __END__