当前位置: 首页 > news >正文

使用JAVA进行MD5加密后所遇到的一些问题

  前言:这几天在研究apache shiro如何使用,这好用到了给密码加密的地方,就碰巧研究了下java的MD5加密是如何实现的,下面记录下我遇到的一些小问题。

 

  使用java进行MD5加密非常的简单,代码如下:

  public static void main(String[] args) throws Exception
    {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        String password = "wodemima";
        byte[] bytes = md5.digest(password.getBytes());
    }

  但是,当我将bytes直接转换成字符串并且存入数据库的时候我发现了问题,怎么显示的是个乱码呢,显示的是如下乱码:

�'D���:�@�
��&

  我顿时感觉这真是加密了,肯定妥妥的破解不了,但是一般加密后显示的是32位16进制字符串,为什么我这显示乱码了呢。原来是还有一个步骤,就是需要将byte数组转换成16进行,代码如下:

  public static void main(String[] args) throws Exception
    {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        String password = "wodemima";
        byte[] bytes = md5.digest(password.getBytes());
        String result = "";
        for(byte b : bytes)
        {
            result = result + Integer.toHexString(b);
        }
        System.out.println(result);
    }
  //输出显示:fffffffb2744ffffffd1ffffffe419ffffff813affffffde40ffffffefaffffff97ffffffc5261f

  这下子算是像模像样了,但是貌似不是32位,并且有好多fff,原来是返回的byte数组当中有负数,但是有负数为什么会造成这样的结果呢,于是乎我就复习了下java当中的基本类型。

  基本类型表如下:
数据类型            大小                  范围                                             默认值 

byte(字节)          8                 -128 - 127                                            0
shot(短整型)        16               -32768 - 32767                                         0
int(整型)           32            -2147483648 - 2147483647                                  0
long(长整型)        64    -9233372036854477808-9233372036854477807                          0        
float(浮点型)       32          1.4E-45 - 3.40292347E+38                                0.0f
double(双精度)      64       4.9E-324 - 1.79769313486231570E+308                      0.0d
char(字符型)        16            ‘ \u0000 - u\ffff ’                                   ‘\u0000 ’
boolean(布尔型)     1                 true/false                                          false

 

   我原来上大学的时候一直在困惑为什么占8位最大值不是128,后来我发现原来还有个0呢。。不知道算不算是顿悟。。。。。

  于Integer.toHexString(b);方法传入的值是int类型的,所以当我传入byte的时候就会自动转换成int类型,又由于byte类型只占8位并且int类型占32位,所以会进行补位,如果byte是整数的话没什么影响,因为前面补的是0。

  但是如果是负数的话就会出现问题了,例如byte b = -112; byte的2进制表示为:1001 0000,java中是以补码的形式进行表示的。(补码我就不介绍了,可以百度查阅。)这样前面补满22位个1的时候就会出现很多f。

  于是我把代码改成下面这个样子:

  public static void main(String[] args) throws Exception
    {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        String password = "wodemima";
        byte[] bytes = md5.digest(password.getBytes());
        String result = "";
        for(byte b : bytes)
        {
            result = result + Integer.toHexString(b & 0xff);
       //b &
0xff 是为了取低8位
     } 
     System.out.println(result);
  }
  //输出显示:fb2744d1e419813ade40efa97c5261f
 

 

   这次更像那么回事了,但是我查了一下31位。为什么会少一位,原来byte数组中有的值可能小于16,所以转换成16进制的时候用1位就可以表示了。这个时候我们应该在前面加上个0。

  代码如下:

  public static void main(String[] args) throws Exception
    {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        String password = "wodemima";
        byte[] bytes = md5.digest(password.getBytes());
        String result = "";
        for(byte b : bytes)
        {
            String temp = Integer.toHexString(b & 0xff);
            if(temp.length() == 1)
            {
                temp = "0" + temp;
            }
            result = result + temp;
        }
        System.out.println(result);
    }
  //输出显示:fb2744d1e419813ade40ef0a97c5261f
 

 

   好了,这次正确了。这就是我记录的一些问题,有些细节不注意还真不知道怎么回事。

转载于:https://www.cnblogs.com/renchunxiao/p/3411370.html

相关文章:

  • ExpandableListView使用(三)-ScrollView嵌套ExpandableListView,列表显示不全
  • ORACLE中的各种数据类型详细的介绍
  • 一个简单的golang json解析库
  • Java Web笔记 – Servlet中的Filter过滤器的介绍和使用 编写过滤器
  • java.lang.UnsatisfiedLinkError: no rxtxSerial in java.library.path
  • maven中jar、war、pom的区别
  • 尝试使用word发布博客
  • Python之优先级问题(待修改)
  • Algs4-2.2.23-3根据经验给出应该在何时为子数组切换到插入排序
  • 提高Vector容器的删除效率
  • Hadoop生态系统之HDFS
  • 使用迅雷下载百度网盘2G以上文件
  • JavaScript学习(一)
  • hadoop2.2.0 + hbase 0.94 + hive 0.12 配置记录
  • NOIP2018提高组省一冲奖班模测训练(四)
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • ECMAScript6(0):ES6简明参考手册
  • Intervention/image 图片处理扩展包的安装和使用
  • JS变量作用域
  • passportjs 源码分析
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • Web标准制定过程
  • 后端_MYSQL
  • 那些被忽略的 JavaScript 数组方法细节
  • 数据可视化之 Sankey 桑基图的实现
  • 原生js练习题---第五课
  • AI算硅基生命吗,为什么?
  • # 数论-逆元
  • (C++17) optional的使用
  • (C语言)字符分类函数
  • (ZT)薛涌:谈贫说富
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • ./和../以及/和~之间的区别
  • .Net FrameWork总结
  • .NET/C# 使用反射注册事件
  • .NET4.0并行计算技术基础(1)
  • .net专家(高海东的专栏)
  • //解决validator验证插件多个name相同只验证第一的问题
  • @Autowired标签与 @Resource标签 的区别
  • @property python知乎_Python3基础之:property
  • @RequestMapping处理请求异常
  • @开发者,一文搞懂什么是 C# 计时器!
  • [ C++ ] template 模板进阶 (特化,分离编译)
  • [100天算法】-目标和(day 79)
  • [BUG] Authentication Error
  • [C++]拼图游戏
  • [C++]运行时,如何确保一个对象是只读的
  • [CTF]2022美团CTF WEB WP
  • [Django 0-1] Core.Handlers 模块
  • [Django开源学习 1]django-vue-admin