【问题标题】:Am I avoiding Hash collisions with this solution?我是否避免与此解决方案发生哈希冲突?
【发布时间】:2013-10-01 20:34:10
【问题描述】:

我在页面上有一个 textarea 元素,单击我创建的保存按钮后,它的内容会保存到我的数据库中。我想使用我保存包含文本区域中信息的记录的表行的唯一 id(主键)创建带有哈希 id 的短网址,例如“MySite.com/laHquq”:http://www.hashids.org/ 这将“从数字生成短哈希(如 YouTube 和 Bitly)。”我想用它来混淆表行的唯一主键与包含来自文本区域的信息的记录。

我将有一个脚本在地址栏中我的域名末尾的正斜杠之后放置创建的哈希 ID(这是混淆主键),因此地址栏现在将具有:“MySite. com/laHquq”信息保存到我的数据库后。这样做只是为了表明现在可以通过访问带有正斜杠后的哈希 id 的站点再次看到保存在 textarea 中的信息。

我还将有一个带有自调用函数的脚本,该函数将在每次页面加载时从地址栏中获取 url,并在正斜杠后检查哈希 id,然后使用哈希 id 从db 显示在页面的 textarea 中。我想知道使用 hashids:http://www.hashids.org/ 是否有助于防止哈希冲突。

【问题讨论】:

标签: javascript html


【解决方案1】:

发现碰撞。

        'main' => [
            'salt' => 'KorvpalliSuuruneTennisePall666',
            'length' => '8',
            'alphabet' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890',
        ],
Hashids::encode(250) results DoGxYxgJ
Hashids::encode(294) results DoGxYxgJ

【讨论】:

  • 区分大小写的“Y”。根据我的测试,不是碰撞。
【解决方案2】:

在此处显示使用 PHP 的经验结果。 我们测试了最少 5 个字符,这种盐如下所示:

$hashids = new Hashids\Hashids('this is my salt', 5, 'BCDFGHJKLMNPQRSTVWXYZ0123456789');

在一个循环中运行一周 24x7 的进程以填充 MySQL DB 中的行,从 1 开始散列 PK,在如下表中:

create table hashids (
    id int NOT NULL AUTO_INCREMENT primary key,
    hash varchar(255)
);

在哈希中使用唯一索引并在脚本期间控制 ON DUPLICATE KEY 并在流程结束时运行 SELECT DISTINCT 以进行完整性检查。

我们停止了进程

select count(*) from hashids;
+-----------+
| count(*)  |
+-----------+
| 355325777 |
+-----------+

然后我们决定从接近签名 BIGINT 的上限开始。

ID: 9223372036854775000-> HASH: RQ0ZPNPPPZ6Q7RNV
ID: 9223372036854775329-> HASH: YN2K8Y888K7NW6VY
ID: 9223372036854775654-> HASH: 2MQ0474440VM8QMY
ID: 9223372036854775777-> HASH: 7L25R7RRR5ZL820W
ID: 9223372036854775805-> HASH: 020WV7VVVWX250YM
ID: 9223372036854775807-> HASH: QVMZYRYYYZXVLM0W

在这两种情况下,在运行了几天并填充了 15Gb 的 id 后,哈希值仍然存在。

我们确认目前未发现任何冲突。

这个测试远远超出了我们的应用程序的限制,所以我们认为 Hashids 对我们来说是安全的。当然,就像在数学中一样,经验结果并不能证明规律。

另外请记住,Hashids 在达到有符号/无符号 BIGINT MySQL DB 限制或 PHP_INT_MAX 之前,至少在 PHP 中是有上限的。

【讨论】:

  • 我知道我迟到了,但是...重要的是要理解,如果一个算法可以创建冲突,它将创建它们.在一点。 Hashing 是一种有损操作,因此会产生无法恢复的冲突。 Hashids 提供了无损的双向算法,结果总是可以恢复的。因此,这意味着当输入不同时,输出也会不同。此外,只要输入相同,输出也将相同。总是。
【解决方案3】:

从文档看来,您永远不会遇到与 hashid 的冲突。那是因为它不是哈希。这是一个密码 - 一种加密算法。虽然是一个非常弱的,但足以生成看起来像哈希的 id。

一个关键线索是有一个decrypt 函数。真正的散列,可以碰撞的散列,不能被解密为单个值,因为有多个值(通常是无限的)生成相同的散列。

在某些方面它类似于 base64 编码,但选择了对 URL 友好的字符集(不是 + 或 /)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多