• JavaUtil_01_MD5加密


    一、百度翻译MD5工具类

    昨天做java微信开发,引用百度翻译API给公众号添加翻译功能时,需要使用MD5生成签名。注意,使用MD5生成签名后一定要转成小写,不然百度翻译后台不会认你这个签名的,会报无效签名的错误。

    百度给出的MD5加密算法示例:

      1 package com.baidu.translate.demo;
      2 
      3 import java.io.File;
      4 import java.io.FileInputStream;
      5 import java.io.FileNotFoundException;
      6 import java.io.IOException;
      7 import java.io.InputStream;
      8 import java.security.MessageDigest;
      9 import java.security.NoSuchAlgorithmException;
     10 
     11 /**
     12  * MD5编码相关的类
     13  * 
     14  * @author wangjingtao
     15  * 
     16  */
     17 public class MD5 {
     18     // 首先初始化一个字符数组,用来存放每个16进制字符
     19     private static final char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
     20             'e', 'f' };
     21 
     22     /**
     23      * 1.获得一个字符串的MD5值
     24      * 
     25      * @param input 输入的字符串
     26      * @return 输入字符串的MD5值
     27      * 
     28      */
     29     public static String md5(String input) {
     30         if (input == null)
     31             return null;
     32 
     33         try {
     34             // 拿到一个MD5转换器(如果想要SHA1参数换成”SHA1”)
     35             MessageDigest messageDigest = MessageDigest.getInstance("MD5");
     36             // 输入的字符串转换成字节数组
     37             byte[] inputByteArray = input.getBytes("utf-8");
     38             // inputByteArray是输入字符串转换得到的字节数组
     39             messageDigest.update(inputByteArray);
     40             // 转换并返回结果,也是字节数组,包含16个元素
     41             byte[] resultByteArray = messageDigest.digest();
     42             // 字符数组转换成字符串返回
     43             return byteArrayToHex(resultByteArray);
     44         } catch (NoSuchAlgorithmException e) {
     45             return null;
     46         }
     47     }
     48 
     49     /**
     50      * 2.获取文件的MD5值
     51      * 
     52      * @param file
     53      * @return
     54      */
     55     public static String md5(File file) {
     56         try {
     57             if (!file.isFile()) {
     58                 System.err.println("文件" + file.getAbsolutePath() + "不存在或者不是文件");
     59                 return null;
     60             }
     61 
     62             FileInputStream in = new FileInputStream(file);
     63 
     64             String result = md5(in);
     65 
     66             in.close();
     67 
     68             return result;
     69 
     70         } catch (FileNotFoundException e) {
     71             e.printStackTrace();
     72         } catch (IOException e) {
     73             e.printStackTrace();
     74         }
     75 
     76         return null;
     77     }
     78      //3.
     79     public static String md5(InputStream in) {
     80 
     81         try {
     82             MessageDigest messagedigest = MessageDigest.getInstance("MD5");
     83 
     84             byte[] buffer = new byte[1024];
     85             int read = 0;
     86             while ((read = in.read(buffer)) != -1) {
     87                 messagedigest.update(buffer, 0, read);
     88             }
     89 
     90             in.close();
     91 
     92             String result = byteArrayToHex(messagedigest.digest());
     93 
     94             return result;
     95         } catch (NoSuchAlgorithmException e) {
     96             e.printStackTrace();
     97         } catch (FileNotFoundException e) {
     98             e.printStackTrace();
     99         } catch (IOException e) {
    100             e.printStackTrace();
    101         }
    102 
    103         return null;
    104     }
    105     //4.字符数组转字符串
    106     private static String byteArrayToHex(byte[] byteArray) {
    107         // new一个字符数组,这个就是用来组成结果字符串的(解释一下:一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方))
    108         char[] resultCharArray = new char[byteArray.length * 2];
    109         // 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去
    110         int index = 0;
    111         for (byte b : byteArray) {
    112             resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
    113             resultCharArray[index++] = hexDigits[b & 0xf];
    114         }
    115 
    116         // 字符数组组合成字符串返回
    117         return new String(resultCharArray);
    118 
    119     }
    120 
    121 }
    View Code

    二、脚本之家MD5工具类

    脚本之家关于MD5的讲解很详细,传送门http://www.jb51.net/article/86027.htm

    1.对字符串进行MD5加密

     1 /**
     2  * 对字符串md5加密
     3  *
     4  * @param str
     5  * @return
     6  */
     7 import java.security.MessageDigest;
     8 public static String getMD5(String str) {
     9  try {
    10  // 生成一个MD5加密计算摘要
    11  MessageDigest md = MessageDigest.getInstance("MD5");
    12  // 计算md5函数
    13  md.update(str.getBytes());
    14  // digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
    15  // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
    16  return new BigInteger(1, md.digest()).toString(16);
    17  } catch (Exception e) {
    18  throw new SpeedException("MD5加密出现错误");
    19  }
    20 }
    View Code

    2.MD5加解密工具类

    (1)MD5加密以及解密类

      1 package com.zyg.security.md5;
      2  
      3 import java.io.UnsupportedEncodingException;
      4 import java.security.MessageDigest;
      5 import java.security.NoSuchAlgorithmException;
      6 import java.security.SecureRandom;
      7 import java.util.Arrays;
      8  
      9 public class MyMD5Util {
     10   
     11  private static final String HEX_NUMS_STR="0123456789ABCDEF";
     12  private static final Integer SALT_LENGTH = 12;
     13   
     14  /** 
     15  * 将16进制字符串转换成字节数组 
     16  * @param hex 
     17  * @return 
     18  */
     19  public static byte[] hexStringToByte(String hex) {
     20  int len = (hex.length() / 2);
     21  byte[] result = new byte[len];
     22  char[] hexChars = hex.toCharArray();
     23  for (int i = 0; i < len; i++) {
     24  int pos = i * 2;
     25  result[i] = (byte) (HEX_NUMS_STR.indexOf(hexChars[pos]) << 4
     26  | HEX_NUMS_STR.indexOf(hexChars[pos + 1]));
     27  }
     28  return result;
     29  }
     30  
     31   
     32  /**
     33  * 将指定byte数组转换成16进制字符串
     34  * @param b
     35  * @return
     36  */
     37  public static String byteToHexString(byte[] b) {
     38  StringBuffer hexString = new StringBuffer();
     39  for (int i = 0; i < b.length; i++) {
     40  String hex = Integer.toHexString(b[i] & 0xFF);
     41  if (hex.length() == 1) {
     42  hex = '0' + hex;
     43  }
     44  hexString.append(hex.toUpperCase());
     45  }
     46  return hexString.toString();
     47  }
     48   
     49  /**
     50  * 验证口令是否合法
     51  * @param password
     52  * @param passwordInDb
     53  * @return
     54  * @throws NoSuchAlgorithmException
     55  * @throws UnsupportedEncodingException
     56  */
     57  public static boolean validPassword(String password, String passwordInDb)
     58  throws NoSuchAlgorithmException, UnsupportedEncodingException {
     59  //将16进制字符串格式口令转换成字节数组
     60  byte[] pwdInDb = hexStringToByte(passwordInDb);
     61  //声明盐变量
     62  byte[] salt = new byte[SALT_LENGTH];
     63  //将盐从数据库中保存的口令字节数组中提取出来
     64  System.arraycopy(pwdInDb, 0, salt, 0, SALT_LENGTH);
     65  //创建消息摘要对象
     66  MessageDigest md = MessageDigest.getInstance("MD5");
     67  //将盐数据传入消息摘要对象
     68  md.update(salt);
     69  //将口令的数据传给消息摘要对象
     70  md.update(password.getBytes("UTF-8"));
     71  //生成输入口令的消息摘要
     72  byte[] digest = md.digest();
     73  //声明一个保存数据库中口令消息摘要的变量
     74  byte[] digestInDb = new byte[pwdInDb.length - SALT_LENGTH];
     75  //取得数据库中口令的消息摘要
     76  System.arraycopy(pwdInDb, SALT_LENGTH, digestInDb, 0, digestInDb.length);
     77  //比较根据输入口令生成的消息摘要和数据库中消息摘要是否相同
     78  if (Arrays.equals(digest, digestInDb)) {
     79  //口令正确返回口令匹配消息
     80  return true;
     81  } else {
     82  //口令不正确返回口令不匹配消息
     83  return false;
     84  }
     85  }
     86  
     87  
     88  /**
     89  * 获得加密后的16进制形式口令
     90  * @param password
     91  * @return
     92  * @throws NoSuchAlgorithmException
     93  * @throws UnsupportedEncodingException
     94  */
     95  public static String getEncryptedPwd(String password)
     96  throws NoSuchAlgorithmException, UnsupportedEncodingException {
     97  //声明加密后的口令数组变量
     98  byte[] pwd = null;
     99  //随机数生成器
    100  SecureRandom random = new SecureRandom();
    101  //声明盐数组变量
    102  byte[] salt = new byte[SALT_LENGTH];
    103  //将随机数放入盐变量中
    104  random.nextBytes(salt);
    105  
    106  //声明消息摘要对象
    107  MessageDigest md = null;
    108  //创建消息摘要
    109  md = MessageDigest.getInstance("MD5");
    110  //将盐数据传入消息摘要对象
    111  md.update(salt);
    112  //将口令的数据传给消息摘要对象
    113  md.update(password.getBytes("UTF-8"));
    114  //获得消息摘要的字节数组
    115  byte[] digest = md.digest();
    116  
    117  //因为要在口令的字节数组中存放盐,所以加上盐的字节长度
    118  pwd = new byte[digest.length + SALT_LENGTH];
    119  //将盐的字节拷贝到生成的加密口令字节数组的前12个字节,以便在验证口令时取出盐
    120  System.arraycopy(salt, 0, pwd, 0, SALT_LENGTH);
    121  //将消息摘要拷贝到加密口令字节数组从第13个字节开始的字节
    122  System.arraycopy(digest, 0, pwd, SALT_LENGTH, digest.length);
    123  //将字节数组格式加密后的口令转化为16进制字符串格式的口令
    124  return byteToHexString(pwd);
    125  }
    126 }
    View Code

    (2)测试类——Client

     1 package com.zyg.security.md5;
     2  
     3 import java.io.UnsupportedEncodingException;
     4 import java.security.NoSuchAlgorithmException;
     5 import java.util.HashMap;
     6 import java.util.Map;
     7  
     8 public class Client {
     9  private static Map users = new HashMap();
    10   
    11  public static void main(String[] args){
    12  String userName = "zyg";
    13  String password = "123";
    14  registerUser(userName,password);
    15   
    16  userName = "changong";
    17  password = "456";
    18  registerUser(userName,password);
    19   
    20  String loginUserId = "zyg";
    21  String pwd = "1232";
    22  try {
    23  if(loginValid(loginUserId,pwd)){
    24  System.out.println("欢迎登陆!!!");
    25  }else{
    26  System.out.println("口令错误,请重新输入!!!");
    27  }
    28  } catch (NoSuchAlgorithmException e) {
    29  // TODO Auto-generated catch block
    30  e.printStackTrace();
    31  } catch (UnsupportedEncodingException e) {
    32  // TODO Auto-generated catch block
    33  e.printStackTrace();
    34  } 
    35  }
    36   
    37  /**
    38  * 注册用户
    39  * 
    40  * @param userName
    41  * @param password
    42  */
    43  public static void registerUser(String userName,String password){
    44  String encryptedPwd = null;
    45  try {
    46  encryptedPwd = MyMD5Util.getEncryptedPwd(password);
    47   
    48  users.put(userName, encryptedPwd);
    49   
    50  } catch (NoSuchAlgorithmException e) {
    51  // TODO Auto-generated catch block
    52  e.printStackTrace();
    53  } catch (UnsupportedEncodingException e) {
    54  // TODO Auto-generated catch block
    55  e.printStackTrace();
    56  }
    57  }
    58   
    59  /**
    60  * 验证登陆
    61  * 
    62  * @param userName
    63  * @param password
    64  * @return
    65  * @throws UnsupportedEncodingException 
    66  * @throws NoSuchAlgorithmException 
    67  */
    68  public static boolean loginValid(String userName,String password) 
    69  throws NoSuchAlgorithmException, UnsupportedEncodingException{
    70  String pwdInDb = (String)users.get(userName);
    71  if(null!=pwdInDb){ // 该用户存在
    72  return MyMD5Util.validPassword(password, pwdInDb);
    73  }else{
    74  System.out.println("不存在该用户!!!");
    75  return false;
    76  }
    77  }
    78 }
    View Code
  • 相关阅读:
    【NLP_Stanford课堂】最小编辑距离
    【NLP_Stanford课堂】句子切分
    【NLP_Stanford课堂】词形规范化
    【NLP_Stanford课堂】分词
    【NLP_Stanford课堂】正则表达式
    【Python自然语言处理】第一章学习笔记——搜索文本、计数统计和字符串链表
    【C++ Primer】详解C++和C中的float中的有效数字
    【C++ Primer】读书笔记_第一章
    【SQL Server 2012】按倒序存储“分组统计”结果的临时表到新建表
    Git学习
  • 原文地址:https://www.cnblogs.com/shirui/p/7344204.html
Copyright © 2020-2023  润新知