#hash-values #url #stable #secure #collection #cryptography #short

url-hash

提供安全稳定的URL哈希值的简单类型

1 个不稳定版本

0.1.0 2024年1月3日

#1018算法

自定义许可

20KB
198

包 url-hash

此包提供了三种类型,专门用于表示Url类型的哈希值。

对于一些以URL为中心的结构,如RDF图和XML文档,管理类似于哈希的操作来比较URL值或检测URL在缓存中的存在成为一个核心需求。虽然可以使用Rust内置的哈希实现,以及扩展的集合如HashMapHashSet,但它们提供了一个封闭的实现,无法在不进行额外努力的情况下以语言可移植或持久的方式使用。

UrlHash类型的目的在于提供表示单个URL值的稳定值的稳定加密哈希,该值可以在不同的平台和编程环境中复制。

示例

use url::Url;
use url_hash::UrlHash;

let url = Url::parse("https://doc.rust-lang.net.cn/").unwrap();
let hash =  UrlHash::from(url);
println!("{}", hash);

规范

本节尝试以语言和平台无关的方式描述实现,以便在其他地方复制。

计算

哈希的基础是SHA-256摘要算法,该算法在部分规范化的URL上计算。

  1. URL的scheme组件被转换为小写。
  2. URL的host组件被转换为小写。
  3. host组件通过punycode替换进行Unicode标准化。
  4. 如果port组件对于给定的方案是默认的(对于http是80,对于https是443等),则将其删除。
  5. URL的path组件中删除任何相对组件(使用"."".."指定)。
  6. path组件被替换为"/"
  7. pathqueryfragment组件进行URL编码。

以下表格演示了上述规则的一些结果。

# 输入 输出
1 hTTpS://example.com/ https://example.com/
2 https://Example.COM/ https://example.com/
3 https://exámple.com/ https://xn--exmple-xta.com/
3 https://example§.com/ https://xn--example-eja.com/
4 http://example.com:80/ http://example.com/
4 https://example.com:443/ https://example.com/
5 https://example.com/foo/../bar/./baz.jpg https://example.com/bar/baz.jpg
6 https://example.com https://example.com/
7 https://example.com/hello world https://example.com/hello%20world
7 https://example.com/?q=hello world https://example.com/?q=hello%20world
7 https://example.com/?q=hello#to world https://example.com/?q=hello#to%20world

表示

生成的SHA-256是一个256位,或32字节的值。这被存储为四个64位(8字节)的无符号整数值,这些值从以小端顺序表示的摘要字节转换而来。以下代码演示了如何从表示摘要的字节创建这些值。

以下代码演示了如何从摘要字节创建这四个值。

let bytes: [u8;32] = digest_bytes();

let value_1 = u64::from_le_bytes(bytes[0..8].try_into().unwrap());
let value_2 = u64::from_le_bytes(bytes[8..16].try_into().unwrap());
let value_3 = u64::from_le_bytes(bytes[16..24].try_into().unwrap());
let value_4 = u64::from_le_bytes(bytes[24..32].try_into().unwrap());

简写形式

在某些情况下,当在空间和哈希冲突之间进行权衡时,没有必要存储或传递整个32字节的UrlHash值。为了允许这些权衡,每个UrlHash实例都可以转换为16字节的UrlShortHash,它只包含完整哈希的前两个64位无符号值,或者8字节的UrlVeryShortHash,它只包含完整哈希的第一个64位无符号值。

以下代码演示了创建简短(截断)哈希以及前缀测试starts_withstarts_with_just

let url = Url::parse("https://doc.rust-lang.net.cn/").unwrap();
let hash =  UrlHash::from(url);

let short = hash.short();
assert!(hash.starts_with(&short));

let very_short = hash.very_short();
assert!(short.starts_with(&very_short));
assert!(hash.starts_with_just(&very_short));

assert_eq!(very_short, hash.very_short());

变更历史

版本 0.1.0

  • 首次发布。

依赖项

~6–14MB
~277K SLoC