繁体   English   中英

Java将哈希转换为随机字符串

[英]Java convert hash to random string

我正在尝试开发一种在彩虹表生成器中使用的缩减功能。

缩减函数背后的基本原理是它接受散列,执行一些计算,并返回一定长度的字符串。

目前我正在使用SHA1哈希,我需要返回一个长度为3的字符串。 我需要在以下任意三个随机字符上组成字符串:

abcdefghijklmnopqrstuvwxyz0123456789

我面临的主要问题是我编写的任何缩减函数总是返回已经生成的字符串。 一个好的缩减函数只会很少返回重复的字符串。

有人可以提出任何想法来实现这一目标吗? 或者对哈希到字符串操作的任何建议都会很棒。

提前致谢

玩笑

所以听起来你有20个数字的基数255(SHA1哈希的长度),你需要映射到基数36的三个数字。我只是从哈希字节,模数36 ^ 3和一个BigInteger ,返回基数36中的字符串。

public static final BigInteger N36POW3 = new BigInteger(""+36*36*36));
public static String threeDigitBase36(byte[] bs) {
  return new BigInteger(bs).mod(N36POW3).toString(36);
}
// ...
threeDigitBase36(sha1("foo")); // => "96b"
threeDigitBase36(sha1("bar")); // => "y4t"
threeDigitBase36(sha1("bas")); // => "p55"
threeDigitBase36(sha1("zip")); // => "ej8"

当然会有碰撞,就像你将任何空间映射到一个较小的空间时一样,但是熵应该比上面的解决方案更好。

应用KISS原则:

  • SHA只是一个字符串
  • String的JDK哈希码是“随机的”
  • Integer可以在任何基础上呈现

这一行代码就是这样的:

public static String shortHash(String sha) {
    return Integer.toString(sha.hashCode() & 0x7FFFFFFF, 36).substring(0, 3);
}

注意: & 0x7FFFFFFF将符号位置零(哈希码可以是负数,否则将使用前导减号进行渲染)。

编辑 - 保证哈希长度

我的原始解决方案是天真的 - 当int哈希小于100 (基数36)时它没有处理这种情况 - 这意味着它将打印少于3个字符。 此代码修复了这一点,同时仍保持值“随机”。 它还避免了substring()调用,因此性能应该更好。

static int min = Integer.parseInt("100", 36);
static int range = Integer.parseInt("zzz", 36) - min;

public static String shortHash(String sha) {
    return Integer.toString(min + (sha.hashCode() & 0x7FFFFFFF) % range, 36);
}

此代码通过强制它在100zzz之间保证最终散列有3个字符 - 基数36中的最低和最高3字符散列,同时仍然使其“随机”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM