首页 > 解决方案 > 在生成类似 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];
        }
    }

但这会产生完全错误的结果,我只是提出这个来展示我的问题是什么。在这种情况下,我能做些什么来保证字符串以及成员的唯一性?

标签: php

解决方案


解决了!这个网站的界面可以像开关一样开启批判性思维……

$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. 这段代码只是从整个总和中减去每个字符串的最后一个字节。现在所有要求都满足了。


推荐阅读