小型Java类,用于从一个或多个数字生成类似YouTube的哈希值。
由Ivan Akimov从javascript hashids.js移植
hashids(哈希ID)从无符号(长)整数创建短的,唯一的,可解码的哈希。
它是为网站设计的,用于URL缩短,跟踪内容或将页面设为私有(或至少不可猜测)。
该算法尝试满足以下要求:
而不是显示的项目1
,2
或者3
,你可以告诉他们的U6dc
,u87U
和HMou
。您不必将这些散列存储在数据库中,但是可以即时进行编码和解码。
所有(长)整数都必须大于或等于零。
添加依赖项
哈希值在Maven Central中可用。如果您使用的是Maven,请将以下依赖项添加到pom.xml的依赖项中:
org.hashids
hashids
1.0.3
另外,如果您使用gradle或在android上,请build.gradle
在依赖项下将以下内容添加到应用程序的文件中:
compile 'org.hashids:hashids:1.0.3'
导入包裹
导入 org.hashids ;
编码一个数字
您可以传递唯一的盐值,因此您的哈希值不同于其他所有人的哈希值。我以“这是我的盐”为例。
Hashids hashids = new Hashids(“这是我的盐”);
字符串 hash = hashids 。编码(12345L);
hash
现在将是:
NkK9
解码
注意,在解码期间,使用相同的盐值:
Hashids hashids = new Hashids(“这是我的盐”);
long []数字=哈希值。解码(“ NkK9 ”);
numbers
现在将是:
[ 12345 ]
用不同的盐解码
如果更改盐,解码将不起作用:
Hashids hashids = new Hashids(“这是我的胡椒粉”);
long []数字=哈希值。解码(“ NkK9 ”);
numbers
现在将是:
[]
编码多个数字
Hashids hashids = new Hashids(“这是我的盐”);
字符串 hash = hashids 。编码(683L,94108L,123L,5L);
hash
现在将是:
aBMswoO2UB3Sj
解码方式相同
Hashids hashids = new Hashids(“这是我的盐”);
long []数字=哈希值。解码(“ aBMswoO2UB3Sj ”);
numbers
现在将是:
[ 683, 94108, 123, 5 ]
编码并指定最小哈希长度
在这里,我们对整数1进行编码,并将最小哈希长度设置为8(默认值为0,这意味着哈希将是最短的长度)。
Hashids hashids = 新 Hashids(“这是我的盐”,8);
字符串 hash = hashids 。编码(1L);
hash
现在将是:
gB0NV05e
解码
Hashids hashids = 新 Hashids(“这是我的盐”,8);
long []数字=哈希值。解码(“ gB0NV05e ”);
numbers
现在将是:
[ 1 ]
指定自定义哈希字母
在这里,我们将字母设置为仅包含六个字母:“ 0123456789abcdef”
Hashids hashids = new Hashids(“这是我的盐”,0,“ 0123456789abcdef ”);
字符串 hash = hashids 。编码(1234567L);
hash
现在将是:
b332db5
除了对长值进行编码和解码外,Hashids还提供用于以十六进制表示法对ID(例如由MongoDB生成的对象ID)进行编码和解码的功能。
Hashids hashids = new Hashids(“这是我的盐”);
字符串 hash = hashids 。encodeHex(“ 507f1f77bcf86cd799439011 ”); // goMYDnAezwurPKWKKxL2
字符串 objectId = hashids 。encodeHex(hash); // 507f1f77bcf86cd799439011
注意,用于对十六进制值进行编码和解码的算法与用于对长值进行编码和解码的算法不兼容。这意味着您不能使用decodeHex
提取使用编码的长id的十六进制表示形式encode
。
哈希值的主要目的是混淆ID。它不是为了安全目的或压缩目的而使用或经过测试的。话虽如此,该算法确实试图使这些哈希值变得不可猜测和不可预测:
重复号码
Hashids hashids = new Hashids(“这是我的盐”);
字符串 hash = hashids 。编码(5L,5L,5L,5L);
您看不到任何重复的模式,这些模式可能显示哈希中有4个相同的数字:
1Wc8cwcE
与递增数字相同:
Hashids hashids = new Hashids(“这是我的盐”);
字符串 hash = hashids 。编码(1L,2L,3L,4L,5L,6L,7L,8L,9L,10L);
hash
将会 :
kRHnurhptKcjIDTWC3sx
Hashids hashids = new Hashids(“这是我的盐”);
字符串 hash1 = hashids 。编码(1L); / * NV * /
字符串 hash2 =哈希值。编码(2L); / * 6m * /
字符串 hash3 = hashids 。编码(3L); / * yD * /
字符串 hash4 =哈希值。编码(4L); / * 2l * /
字符串 hash5 =哈希值。编码(5L); / * rD * /
我编写此类的目的是将这些哈希放置在可见的位置,例如URL。如果我为每个用户创建一个唯一的哈希,那么不幸的是,如果哈希最终成为一个坏词,那将是不幸的。想象一下,自动为您的用户创建一个带有哈希的网址,如下所示-http://example.com/user/a**hole
因此,该算法尝试避免使用默认字母生成最常见的英语诅咒词。这是通过切勿将以下字母彼此相邻来完成的:
c, C, s, S, f, F, h, H, u, U, i, I, t, T
原始和参考实现是JS(Hashids网站)版本。JS的number
限制为(2^53 - 1)
。我们的java实现使用Long
,但出于兼容性考虑,限于JS的相同限制。如果提供的数字更大,IllegalArgumentException
将抛出。