MurmurHash算法初探

简介

简单讨论一下MurmurHash算法,之后会依此做一个简易的短链接项目,尽量快些做出来,分享出来😁

既然是初探,我只会去说怎么使用,至于原理,就留到有机会(doge)再来探究吧😂

在一周前我对这个算法也是闻所未闻,至到我看了这篇高性能短链设计文章,才有所了解。

关于MurmurHash算法,可参考Murmurhash介绍与实现

使用

从上面文章知道,MurmurHash是一种非常高效的加密型哈希算法,随机特征表现的非常好,应用领域也很多,具有较高的平衡性和低碰撞率。

它实现了32位和128HashKey加密,这里直接使用Google提供的guava

pom依赖

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.1-jre</version>
</dependency>

使用如下

创建HashFunction对象,加密即可

public static void main(String[] args) {
    HashFunction hashFunction = Hashing.murmur3_32();
    HashCode hashCode = hashFunction.hashString("https://wnhyang.gitee.io/", StandardCharsets.UTF_8);
    System.out.println(hashCode);
}

结果如下

a453dd36

Process finished with exit code 0

这里不禁有疑问了?

a453dd36是什么东西,第一反应便是16进制数,正好 4 ∗ 8 = 32 4*8=32 48=32位,很完美

找到HashCode接口,看到下面几个方法,都能看懂吧!?

@Beta
public abstract class HashCode {
  HashCode() {}

  /** Returns the number of bits in this hash code; a positive multiple of 8. */
  public abstract int bits();

  /**
   * Returns the first four bytes of {@linkplain #asBytes() this hashcode's bytes}, converted to an
   * {@code int} value in little-endian order.
   *
   * @throws IllegalStateException if {@code bits() < 32}
   */
  public abstract int asInt();

  /**
   * Returns the first eight bytes of {@linkplain #asBytes() this hashcode's bytes}, converted to a
   * {@code long} value in little-endian order.
   *
   * @throws IllegalStateException if {@code bits() < 64}
   */
  public abstract long asLong();

  /**
   * If this hashcode has enough bits, returns {@code asLong()}, otherwise returns a {@code long}
   * value with {@code asBytes()} as the least-significant bytes and {@code 0x00} as the remaining
   * most-significant bytes.
   *
   * @since 14.0 (since 11.0 as {@code Hashing.padToLong(HashCode)})
   */
  public abstract long padToLong();

  /**
   * Returns the value of this hash code as a byte array. The caller may modify the byte array;
   * changes to it will <i>not</i> be reflected in this {@code HashCode} object or any other arrays
   * returned by this method.
   */
  // TODO(user): consider ByteString here, when that is available
  public abstract byte[] asBytes();

    ...

}

加上这些方法,重新来

public static void main(String[] args) {
    HashFunction hashFunction = Hashing.murmur3_32();
    HashCode hashCode = hashFunction.hashString("https://wnhyang.gitee.io/", StandardCharsets.UTF_8);
    System.out.print(hashCode.asInt() + "    ");
    System.out.print(hashCode.padToLong() + "    ");
    System.out.print(hashCode.asBytes() + "    ");
    System.out.print(hashCode.bits() + "    ");
    System.out.println(hashCode);
}

新结果就很舒服了, 2 32 = 4 , 294 , 967 , 296 2^{32}=4,294,967,296 232=4,294,967,296,也就是说,32位的MurmurHash算法最多可以有近43亿,按上面短链接的方法转为62进制,6位足矣, 6 2 6 = 56 , 800 , 235 , 584 62^{6}=56,800,235,584 626=56,800,235,584,有568亿呢。

920474532    920474532    [B@76ed5528    32    a453dd36

Process finished with exit code 0

可是,之后测试了同样的代码,只是把要加密的url变为https://blog.csdn.net/freda1997/article/details/105199265便出现问题了

意料之外的结果

-503738096    3791229200    [B@76ed5528    32    1091f9e1

Process finished with exit code 0

从上面HashCode接口的方法可知asInt()padToLong()区别就在这,从Java基础或者说是计算机基础可知数有有符号数和无符号数一说。有符号数第一位表示符号范围为[ − 2 n − 1 -2^{n-1} 2n1, 2 n − 1 − 1 2^{n-1}-1 2n11],无符号数则没有首位的限制。所以能容易想到是int数值溢出了。

测试验证

public static void main(String[] args) {
    HashFunction hashFunction = Hashing.murmur3_32();
    HashCode hashCode = hashFunction.hashString("https://blog.csdn.net/freda1997/article/details/105199265", StandardCharsets.UTF_8);
    System.out.print(hashCode.asInt() + "    ");
    System.out.print(hashCode.padToLong() + "    ");
    System.out.print(hashCode.asBytes() + "    ");
    System.out.print(hashCode.bits() + "    ");
    System.out.println(hashCode);

    long d = (int) hashCode.padToLong();
    System.out.println(d);
}

果然

-503738096    3791229200    [B@76ed5528    32    1091f9e1
-503738096

Process finished with exit code 0

上面就展示了怎么使用MurmurHash算法,之后就可着手开始短链接项目了。😏

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无奈何杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值