php - 在生成类似 LtHash 的总和时,保证字符串的唯一性,而不考虑其字符位置
问题描述
我正在尝试完成LtHash提供的功能,而不考虑安全概念:从项目列表中计算总和,而不管它们的顺序如何,然后对其进行散列并将其用作列表的标识。换句话说,我正在尝试比较过去是否已将新项目添加到列表中。
我的输入是:['Item1', 'Item2', 'Item3']
我的输出是:1347
。
下面的代码将我数组中的每个项目解压缩为字节并简单地计算总和:
$sum = 0;
foreach( $collection as $item ) {
$bytes = unpack( 'C*', $item );
$sum += array_sum( $bytes );
}
但这有一个问题。假设我有temI1
而不是Item1
. 这绝对不是同一个项目,但它肯定包含相同的字符(因此相同的字节总和),如果我要更改我的集合以整合此更改,我的总和仍然是1347
.
在计算上述总和时如何避免这个问题?
我尝试遍历每个字符串的每个字节,以从前一个中减去下一个:
foreach( $collection as $item ) {
$bytes = unpack( 'C*', $item );
//Go through each byte from the string.
for( $i = 1; $i <= count( $bytes ); $i++ ) {
//If a next byte exists.
if( isset( $bytes[$i+1] ) ) {
$sum += $bytes[$i] - $bytes[$i+1];
//If not, subtract the last, lone byte from the entire sum.
} else {
$sum += $sum - $bytes[$i];
}
}
但这会产生完全错误的结果,我只是提出这个来展示我的问题是什么。在这种情况下,我能做些什么来保证字符串以及成员的唯一性?
解决方案
解决了!这个网站的界面可以像开关一样开启批判性思维……
$sum = 0;
foreach( $collection as $item ) {
$bytes = unpack( 'C*', $item );
for( $i = 1; $i <= count( $bytes ); $i++ ) {
if( isset( $bytes[$i+1] ) ) {
$sum += $bytes[$i] - $bytes[$i+1];
} else {
$sum -= $bytes[$i];
}
}
}
当它处理每个字符串的最后一个单独的字节时,它将添加到总和中,即sum - lone_byte
. 这段代码只是从整个总和中减去每个字符串的最后一个字节。现在所有要求都满足了。