iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java编码算法与哈希算法如何使用
  • 167
分享到

Java编码算法与哈希算法如何使用

2023-07-04 13:07:11 167人浏览 八月长安
摘要

本篇内容主要讲解“Java编码算法与哈希算法如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java编码算法与哈希算法如何使用”吧!一、编码算法1.什么是编码ASCII 码就是一种编码,字

本篇内容主要讲解“Java编码算法与哈希算法如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java编码算法与哈希算法如何使用”吧!

    一、编码算法

    1.什么是编码

    ASCII 码就是一种编码,字母 A 的编码是十六进制的 0x41 ,字母 B 是 0x42 ,以此类推。

    因为 ASCII 编码最多只能有 127 个字符,要想对更多的文字进行编码,就需要用占用 2个字节的 Unicode 。而中文的"中"字使用 Unicode 编码就是 0x4e2d ,使用 UTF8 则需要 3 个字节编码;因此,最简单的编码是直接给每个字符指定一个若干字节表示的整数,复杂一点的 编码就需要根据一个已有的编码推算出来。比如 UTF-8 编码,它是一种不定长编码, 但可以从给定字符的 Unicode 编码推算出来。

    2.URL编码

    URL 编码是浏览器发送数据给服务器时使用的编码,它通常附加在 URL 的参数部 分,例如: https://www.baidu.com/s?wd=%E4%B8%AD%E6%96%87

    之所以需要 URL 编码,是因为出于兼容性考虑,很多服务器只识别 ASCII 字符。 但如果 URL 中包含中文、日文这些非 ASCII 字符怎么办?不要紧, URL 编码有一套 规则:

    • 如果字符是 A ~ Z , a ~ z , 0 ~ 9 以及 - 、 _ 、 . 、 * ,则保持不变;

    • 如果是其他字符,先转换为 UTF-8 编码,然后对每个字节以 %XX 表示。

    例如:字符"中"的 UTF-8 编码是 0xe4b8ad ,因此,它的 URL 编码 是 %E4%B8%AD 。 URL 编码总是大写。

    Java 标准库提供了一个 URLEncoder 类来对任意字符串进行 URL 编码:

    import java.net.URLEncoder;public class Main {    public static void main(String[] args) {        String encoded = URLEncoder.encode("中文!", "utf-8");System.out.println(encoded);    }}

    上述代码的运行结果是 %E4%B8%AD%E6%96%87%21 ,"中"的 URL 编码 是 %E4%B8%AD ,"文"的URL编码是 %E6%96%87 , ! 虽然是 ASCII 字符,也要对其编 码为 %21 。

    如果服务器收到 URL 编码的字符串,就可以对其进行解码,还原成原始字符串。 Java 标准库的 URLDecoder 就可以解码:

    public class Main {    public static void main(String[] args) {        String decoded = URLDecoder.decode("%E4%B8%AD%E6%96%87%21", "utf-8");System.out.println(decoded);    }}

    特别注意: URL 编码是编码算法,不是加密算法。 URL 编码的目的是把任意文本数据编码为 % 前缀 表示的文本,编码后的文本仅包含 A ~ Z , a ~ z , 0 ~ 9 , - , _ , . , * 和 % ,便于浏览 器和服务器处理。

    3.Base64编码

    URL 编码是对字符进行编码,表示成 %xx 的形式,而 Base64 编码是对二进制数 据进行编码,表示成文本格式。

    Base64 编码可以把任意长度的二进制数据变为纯文本,并且纯文本内容中且只包 含指定字符内容: A ~ Z 、 a ~ z 、 0 ~ 9 、 + 、 / 、 = 。它的原理是把 3 字 节的二进制数据按 6bit 一组,用 4 个int整数表示,然后查表,把 int 整数用索引对 应到字符,得到编码后的字符串。

    6 位整数的范围总是 0 ~ 63 ,所以,能用 64 个字符表示:字符 A ~ Z 对应索 引 0 ~ 25 ,字符 a ~ z 对应索引 26 ~ 51 ,字符 0 ~ 9 对应索引 52 ~ 61 ,最 后两个索引 62 、 63 分别用字符 + 和 / 表示。

    举个例子: 3 个 byte 数据分别是 e4 、 b8 、 ad ,按 6bit 分组得到 39 、 0b 、 22 和 2d :

    ┌───────────────┬───────────────┬───────────────┐
    │      e4       │      b8       │      ad       │
    └───────────────┴───────────────┴───────────────┘
    ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
    │1│1│1│0│0│1│0│0│1│0│1│1│1│0│0│0│1│0│1│0│1│1│0│1│
    └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
    ┌───────────┬───────────┬───────────┬───────────┐
    │    39     │    0b     │    22     │    2d     │
    └───────────┴───────────┴───────────┴───────────┘

    在 Java 中,二进制数据就是 byte[] 数组。 Java 标准库提供了 Base64 来对 byte[] 数组进行编解码:

    public class Main {    public static void main(String[] args) {        byte[] input = new byte[] { (byte) 0xe4, (byte) 0xb8, (byte) 0xad };        String b64encoded = Base64.getEncoder().encodeToString(input);        System.out.println(b64encoded);    }}

    编码后得到字符串结果: 5Lit4 。要对这个字符使用 Base64 解码,仍然用 Base64 这个类:

    public class Main {    public static void main(String[] args) {        byte[] output = Base64.getDecoder().decode("5Lit");        System.out.println(Arrays.toString(output)); // [-28, -72, -83]    }}

    因为标准的 Base64 编码会出现 + 、 / 和 = ,所以不适合把 Base64 编码后的字符串放到 URL 中。 一种针对 URL 的 Base64 编码可以在 URL 中使用的 Base64 编码,它仅仅是把 + 变成 - , / 变成 _ :

    public class Main {    public static void main(String[] args) {        // 原始字节内容byte[] input = new byte[] { 0x01, 0x02, 0x7f, 0x00 };// 分别使用两种方式进行编码String b64Encode = Base64.getEncoder().encodeToString(input);        String b64UrlEncoded = Base64.getUrlEncoder().encodeToString(input);        // 结果完全一致        System.out.println(b64Encode);         System.out.println(b64UrlEncoded);        // 分别使用两种方式进行重新解码        byte[] output1 = Base64.getDecoder().decode(b64Encode);        System.out.println(Arrays.toString(output1));        byte[] output2 = Base64.getUrlDecoder().decode(b64UrlEncoded);        System.out.println(Arrays.toString(output2));    }}
    • Base64 编码的目的是把二进制数据变成文本格式,这样在很多文本中就可以处理二进 制数据。例如,电子邮件协议就是文本协议,如果要在电子邮件中添加一个二进制文 件,就可以用 Base64 编码,然后以文本的形式传送。

    • Base64 编码的缺点是传输效率会降低,因为它把原始数据的长度增加了1/3。和 URL 编码一样, Base64 编码是一种编码算法,不是加密算法。

    • 如果把 Base64 的 64 个字符编码表换成 32 个、 48 个或者 58 个,就可以使 用 Base32 编码, Base48 编码和 Base58 编码。字符越少,编码的效率就会越低。

    二、哈希算法

    1.概述

    哈希算法( Hash )又称摘要算法( Digest ),它的作用是:对任意一组输入数 据进行计算,得到一个固定长度的输出摘要。哈希算法的目的:为了验证原始数据是否被篡改。

    哈希算法最重要的特点就是:

    • 相同的输入一定得到相同的输出;

    • 不同的输入大概率得到不同的输出。

    Java字符串的 hashCode() 就是一个哈希算法,它的输入是任意字符串,输出是固定 的 4 字节 int 整数:

    "hello".hashCode(); // 0x5e918d2"hello, java".hashCode(); // 0x7a9d88e8"hello, bob".hashCode(); // 0xa0dbae2f

    两个相同的字符串永远会计算出相同的 hashCode ,否则基于 hashCode 定位的 HashMap 就无法正常工 作。这也是为什么当我们自定义一个 class 时,覆写 equals() 方法时我们必须正确覆写 hashCode() 方法。

    2.哈希碰撞

    哈希碰撞是指,两个不同的输入得到了相同的输出:

    "AaAaAa".hashCode(); // 0x7460e8c0"BBAaBB".hashCode(); // 0x7460e8c0"通话".hashCode(); // 0x11ff03"重地".hashCode(); // 0x11ff03

    碰撞能不能避免?答案是不能。碰撞是一定会出现的,因为输出的字节长度是固定的, String 的 hashCode() 输出是 4 字节整数,最多只有 4294967296 种输出,但输入的数据长度是不固定的,有无数种输入。所以,哈希算 法是把一个无限的输入集合映射到一个有限的输出集合,必然会产生碰撞。

    碰撞不可怕,我们担心的不是碰撞,而是碰撞的概率,因为碰撞概率的高低关系到哈希算法的安全性。一个安全的哈希算法必须满足:

    • 碰撞概率低;

    • 不能猜测输出:输入的任意一个 bit 的变化会造成输出完全不同,这样就很难从输出反推输入(只能依靠 暴力穷举)。

    假设一种哈希算法有如下规律:

    hashA("java001") = "123456"hashA("java002") = "123457"hashA("java003") = "123458"

    那么很容易从输出 123459 反推输入,这种哈希算法就不安全。安全的哈希算法从输出是看不出任何规律的:

    hashB("java001") = "123456"hashB("java002") = "580271"hashB("java003") = ???

    3.常用哈希算法

    常用的哈希算法有:根据碰撞概率,哈希算法的输出长度越长,就越难产生碰撞,也就越安全。

    Java编码算法与哈希算法如何使用

    ①.MD5
    import java.security.MessageDigest;public class main {public static void main(String[] args)  {// 创建一个MessageDigest实例:        MessageDigest md = MessageDigest.getInstance("MD5");        // 反复调用update输入数据:        md.update("Hello".getBytes("UTF-8"));        md.update("World".getBytes("UTF-8"));        // 16 bytes: 68e109f0f40ca72a15e05cc22786f8e6        byte[] results = md.digest();         StringBuilder sb = new StringBuilder();        for(byte bite : results) {        sb.append(String.fORMat("%02x", bite));        }        System.out.println(sb.toString());}}

    运行上述代码,可以得到输入HelloWorld 的 MD5 是 68e109f0f40ca72a15e05cc22786f8e6

    使用 MessageDigest 时,我们首先根据哈希算法获取一个 MessageDigest 实例,然后, 反复调用 update(byte[]) 输入数据。当输入结束后,调用 digest() 方法获得 byte [] 数组表示的摘要,最后,把它转换为十六进制的字符串。

    ②.SHA-1
    import java.security.MessageDigest;public class main {public static void main(String[] args)  {// 创建一个MessageDigest实例:        MessageDigest md = MessageDigest.getInstance("SHA-1");        // 反复调用update输入数据:        md.update("Hello".getBytes("UTF-8"));        md.update("World".getBytes("UTF-8"));        // 20 bytes: db8ac1c259eb89d4a131b253bacfca5f319d54f2        byte[] results = md.digest();         StringBuilder sb = new StringBuilder();        for(byte bite : results) {        sb.append(String.format("%02x", bite));        }        System.out.println(sb.toString());}}

    类似的,计算 SHA-256 ,我们需要传入名称" SHA-256 ",计算 SHA-512 ,我们需要传入名称" SHA-512 "。

    ③.RipeMD-160

    BouncyCastle是一个提供了很多哈希算法和加密算法的第三方开源库。它提供了 Java 标准库没 有的一些算法,例如, RipeMD160 哈希算法。 RIPEMD160 是一种基于 Merkle-Damgård 结构的加密哈希函数,它是比特币标准之一。 RIPEMD-160 是 RIPEMD 算法的增强版本, RIPEMD-160 算法可以产生出 160 位的的哈希摘要。

    用法:

    • 首先,我们必须把 BouncyCastle 提供的 bcprov-jdk15on-1.70.jar 添加至 classpath 。

    • 其次,Java标准库的 java.security 包提供了一种标准机制,允许第三方提供商无缝接入。我们要使用 Bouncy Castle 提供的 RipeMD160 算法,需要先把 BouncyCastle 注册一下:

    public class Main {    public static void main(String[] args) throws Exception {        // 注册BouncyCastle提供的通知类对象BouncyCastleProvider        Security.addProvider(new BouncyCastleProvider());        // 获取RipeMD160算法的"消息摘要对象"(加密对象)        MessageDigest md = MessageDigest.getInstance("RipeMD160");        // 更新原始数据        md.update("HelloWorld".getBytes());        // 获取消息摘要(加密)        byte[] result = md.digest();        // 消息摘要的字节长度和内容        System.out.println(result.length); // 160位=20字节        System.out.println(Arrays.toString(result));        // 16进制内容字符串        String hex = new BigInteger(1,result).toString(16);        System.out.println(hex.length()); // 20字节=40个字符        System.out.println(hex);    }}

    4.哈希算法的用途

    校验下载文件

    因为相同的输入永远会得到相同的输出,因此,如果输入被修改了,得到的输出就会不同。

    如何判断下载到本地的软件是原始的、未经篡改的文件?我们只需要自己计算一下本地文件的哈希值,再 与官网公开的哈希值对比,如果相同,说明文件下载正确,否则,说明文件已被篡改。

    存储用户密码

    如果直接将用户的原始口令存放到数据库中,会产生极大的安全风险: 数据库管理员能够看到用户明文口令; 数据库数据一旦泄漏,黑客即可获取用户明文口令。

    到此,相信大家对“Java编码算法与哈希算法如何使用”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

    --结束END--

    本文标题: Java编码算法与哈希算法如何使用

    本文链接: https://www.lsjlt.com/news/345337.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Java编码算法与哈希算法如何使用
      本篇内容主要讲解“Java编码算法与哈希算法如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java编码算法与哈希算法如何使用”吧!一、编码算法1.什么是编码ASCII 码就是一种编码,字...
      99+
      2023-07-04
    • Java编码算法与哈希算法深入分析使用方法
      目录一、编码算法1.什么是编码2.URL编码3.Base64编码二、哈希算法1.概述2.哈希碰撞3.常用哈希算法①.MD5②.SHA-1③.RipeMD-1604.哈希算法的用途三、...
      99+
      2022-11-13
      Java编码算法 Java哈希算法
    • 一篇文章读懂Java哈希与一致性哈希算法
      目录哈希 Hash 算法介绍分布式存储场景场景描述:实现思路:缺点:一致性Hash算法节点增加场景节点减少场景节点分布不均匀虚拟节点增加节点节点减少总结哈希 Hash 算法介绍 哈希...
      99+
      2024-04-02
    • Java数据结构哈希算法之哈希桶方式解决哈希冲突
      一. 实现形式一(键值对只能为整数) 我们可以先实现一个比较简单的哈希表,使用java中解决哈希冲突的方法,即哈希桶(开散列)方式实现,其中注意: 可以使用内部类方式定义节...
      99+
      2024-04-02
    • Java数据结构与算法系列精讲之哈希算法实现
      概述 从今天开始, 小白我将带大家开启 Java 数据结构 & 算法的新篇章. 获取哈希值 hashCode()方法可以返回一个对象的哈希值. 需要注意的是, 我们需要对值...
      99+
      2024-04-02
    • 如何理解一致性哈希算法
      本篇内容介绍了“如何理解一致性哈希算法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!要了解一致性哈希,首先...
      99+
      2024-04-02
    • 如何用PHP实现分布算法之一致性哈希算法
      目录传统算法缺陷算法思想算法实现总结传统算法缺陷 对于服务器分布,我们要考虑的东西有如下三点:数据平均分布,查找定位准确,降低宕机影响。 传统算法一般是将数据的键用算法映射出数字,对...
      99+
      2024-04-02
    • 如何理解哈希算法类型hash-identifier
      这篇文章给大家介绍如何理解哈希算法类型hash-identifier,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。识别哈希算法类型hash-identifierhash-identifier是一款哈希算法识别工具。通过...
      99+
      2023-06-05
    • 怎么使用PHP实现分布算法之一致性哈希算法
      这篇文章主要介绍怎么使用PHP实现分布算法之一致性哈希算法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!传统算法缺陷对于服务器分布,我们要考虑的东西有如下三点:数据平均分布,查找定位准确,降低宕机影响。传统算法一般是...
      99+
      2023-06-15
    • java如何计算字符串的哈希值
      在Java中,可以使用String类的hashCode()方法来计算字符串的哈希值。hashCode()方法返回一个int类型的哈希...
      99+
      2023-09-11
      java
    • .NET6中哈希算法的简化用法的实现
      目录IntroNew APISample BeforeNew API SampleMoreReferencesIntro 微软在 .NET 6 中引入一些更简单的 API 来使用 ...
      99+
      2024-04-02
    • Python底层技术揭秘:如何实现哈希算法
      Python底层技术揭秘:如何实现哈希算法,需要具体代码示例摘要:哈希算法是计算机领域中常用的技术之一,用于快速确定数据的唯一标识。Python作为一门高级语言,提供了许多内建的哈希函数,如hash()函数以及各种散列算法的实现。本文将揭示...
      99+
      2023-11-08
      Python 技术 哈希
    • Python篇——数据结构与算法(第六部分:哈希表)
        目录 1、直接寻址表 2、直接寻址表缺点 3、哈希 4、哈希表 5、解决哈希冲突 6、拉链法 7、常见哈希函数 8、哈希表的实现 8.1迭代器iter()和__iter__ 8.2str()和repr() 8.3代码实现哈希表 8.4哈...
      99+
      2023-09-10
      python 数据结构 算法 哈希算法
    • 详解Java分布式系统中一致性哈希算法
      目录业务场景使用Hash取模的问题1.负载均衡2.分库分表基本思想原理如何提高容错性和扩展性的1. 新增服务器节点2. 删除服务器节点Hash环的数据倾斜问题总结业务场景 近年来B2...
      99+
      2024-04-02
    • 带你了解Java数据结构和算法之哈希表
      目录1、哈希函数的引入①、把数字相加②、幂的连乘2、冲突3、开放地址法①、线性探测②、装填因子③、二次探测④、再哈希法4、链地址法5、桶6、总结1、哈希函数的引入 大家都用过字典,字...
      99+
      2024-04-02
    • java哈希算法HashMap经典面试题目汇总解析
      目录1、HashMap 的数据结构?2、HashMap 的工作原理?3、当两个对象的 hashCode 相同会发生什么?4、你知道 hash 的实现吗?为什么要这样实现?5、为什么要...
      99+
      2024-04-02
    • Java编程:如何使用二维码算法进行编程?
      Java编程:如何使用二维码算法进行编程? 二维码是一种可以编码大量信息的矩阵条码,它可以被扫描器读取,并将信息转换为可读取的格式。在现代社会中,二维码被广泛应用于各个领域,如商品销售、票务、物流等。本文将介绍如何使用Java编程语言实现二...
      99+
      2023-10-21
      npm 二维码 编程算法
    • 怎么用PHP实现自己的sha-256哈希算法
      今天小编给大家分享一下怎么用PHP实现自己的sha-256哈希算法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。哈希 又称作...
      99+
      2023-06-30
    • Java编程:如何使用Bash优化算法?
      在日常的Java编程中,算法优化是一个非常重要的课题。随着数据量的增加,算法的效率会成为制约程序性能的瓶颈。而Bash脚本则是一种可以帮助我们快速优化算法的工具。本文将介绍如何使用Bash优化Java算法,并通过实例演示其具体应用。 一、...
      99+
      2023-06-19
      教程 编程算法 bash
    • Java编程中,如何使用算法提升代码质量?
      在Java编程中,算法对于提升代码质量起着至关重要的作用。使用算法可以优化程序的性能、提高代码可读性和可维护性,同时还能够为程序提供更好的安全性和可靠性。 下面,我们将探讨一些在Java编程中使用算法提升代码质量的方法: 选择正确的算法 ...
      99+
      2023-10-27
      编程算法 javascript shell
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作