• MD5加密 及 防止重复提交


    1.JSP页面

     1 <%@page import="cn.gs.ly.app2.MD5Util"%>
     2 <%@page import="java.util.UUID"%>
     3 <%@page import="java.util.Random"%>
     4 <%@ page language="java" contentType="text/html" pageEncoding="utf-8"%>
     5 <!DOCTYPE html>
     6 <html>
     7 <head>
     8 <title>MD5加密</title>
     9     <script type="text/javascript">
    10         function toSubmit() {
    11             document.getElementById("f1").submit();
    12             document.getElementById("t1").disabled=true;  //点击后不可被选中,防止网络延迟时多次点击
    13         }    
    14     </script>
    15 </head>
    16 <body>
    17     <%
    18         //String token = UUID.randomUUID().toString();    //UUID随机生成唯一的随机号    
    19         String token = ""+System.currentTimeMillis()+new Random().nextLong()+"";
    20         token = MD5Util.md5(token);
    21         session.setAttribute("token", token);  //设置  属性 值为token。  
    22         //后台获取token属性值与隐藏域参数作比较,相同即为同一网页
    23     %>
    24     <form action="RegisterServlet" method="post" id="f1">    
    25         姓名:<input type="text" name="name">
    26         <input type="hidden" name="token" value="<%=token%>"> <!-- 隐藏域存放token值 -->
    27         <input type="button" value="注册" onclick="toSubmit()" id="t1">
    28     </form>
    29 </body>
    30 </html>

    2.JAVA。验证同意网页防止重复提交

     1 package cn.gs.ly.app2;
     2 import java.io.IOException;
     3 import java.io.PrintWriter;
     4 
     5 import javax.servlet.ServletException;
     6 import javax.servlet.http.HttpServlet;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletResponse;
     9 
    10 public class RegisterServlet extends HttpServlet{
    11     @Override
    12     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    13         req.setCharacterEncoding("UTF-8");
    14         resp.setCharacterEncoding("UTF-8");
    15         resp.setContentType("text/html;charset=utf-8");
    16         
    17         String name = req.getParameter("name");
    18         String ftoken = req.getParameter("token");
    19         String stoken = (String)req.getSession().getAttribute("token");
    20         
    21         PrintWriter out = resp.getWriter();    
    22         try {
    23             Thread.sleep(4000); //模拟网络延迟
    24         } catch (InterruptedException e) {
    25             e.printStackTrace();
    26         }
    27         if(ftoken.equals(stoken)){  //已知比未知
    28             System.out.println(name+"   save success"+ftoken);
    29             out.println("<h1>"+name+"  save success</h1>");
    30             req.getSession().removeAttribute("token");
    31         }else{
    32             System.out.println("重复提交");
    33             out.println("<h1>请不要重复提交</h1>");
    34         }    
    35     }
    36     @Override
    37     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    38         this.doPost(req, resp);
    39     }
    40 }

    3.MD5加密。

     1 package cn.gs.ly.app2;
     2 import java.security.MessageDigest;
     3 import java.security.NoSuchAlgorithmException;
     4 
     5 import sun.misc.BASE64Encoder;
     6 public class MD5Util {        
     7     /**
     8      * @param message 要加密的字符串
     9      * @param getInstance()  生成实现指定摘要算法(md5)的 MessageDigest 对象。
    10      * @param digest(message.getBytes())  使用指定的字节数组对摘要进行最后更新,然后完成摘要计算
    11      * @param base64.encode(b) 加密后信息用Base64编码 转为base64的
    12      * @param msg  得到的最终的加密信息
    13      * */
    14     public static String md5(String message){
    15         String msg = "";
    16         try {  
    17             MessageDigest md = MessageDigest.getInstance("md5");  //生成实现指定摘要算法(md5)的 MessageDigest 对象。
    18             System.out.println("加密前:"+new String(message.getBytes()));//加密前信息
    19             byte [] b = md.digest(message.getBytes());    // 使用指定的字节数组对摘要进行最后更新,然后完成摘要计算
    20             System.out.println("加密后:"+new String(b));  //加密后信息
    21             BASE64Encoder base64 = new BASE64Encoder();
    22             msg = base64.encode(b);  //把字节数组转化成字符串     
    23             System.out.println("base64处理后:"+msg);//最终加密信息.MD5加密有的显示为乱码经base64再加密后得到可读性强的形式
    24         } catch (NoSuchAlgorithmException e) {
    25             e.printStackTrace();
    26         }        
    27         return msg;
    28     }
    29 }
    构造方法摘要
    protected MessageDigest(String algorithm) 
              创建具有指定算法名称的MessageDigest 实例对象
     
    方法摘要
     Object clone() 
              如果实现是可复制的,则返回一个副本。
     byte[] digest() 
              通过执行诸如填充之类的最终操作完成哈希计算。
     byte[] digest(byte[] input) 
              使用指定的字节数组对摘要进行最后更新,然后完成摘要计算。
     int digest(byte[] buf, int offset, int len) 
              通过执行诸如填充之类的最终操作完成哈希计算。
     String getAlgorithm() 
              返回标识算法的独立于实现细节的字符串。
     int getDigestLength() 
              返回以字节为单位的摘要长度,如果提供程序不支持此操作并且实现是不可复制的,则返回 0。
    static MessageDigest getInstance(String algorithm) 
              生成实现指定摘要算法的 MessageDigest 对象。
    static MessageDigest getInstance(String algorithm, Provider provider) 
              生成实现指定提供程序提供的指定算法的 MessageDigest 对象,如果该算法可从指定的提供程序得到的话。
    static MessageDigest getInstance(String algorithm, String provider) 
              生成实现指定提供程序提供的指定算法的 MessageDigest 对象,如果该算法可从指定的提供程序得到的话。
     Provider getProvider() 
              返回此信息摘要对象的提供程序。
    static boolean isEqual(byte[] digesta, byte[] digestb) 
              比较两个摘要的相等性。
     void reset() 
              重置摘要以供再次使用。
     String toString() 
              返回此信息摘要对象的字符串表示形式。
     void update(byte input) 
              使用指定的字节更新摘要。
     void update(byte[] input) 
              使用指定的字节数组更新摘要。
     void update(byte[] input, int offset, int len) 
              使用指定的字节数组,从指定的偏移量开始更新摘要。
     void update(ByteBuffer input) 
              使用指定的 ByteBuffer 更新摘要。
    二、实际实践
    2.1、创建 MessageDigest 对象
    计算信息摘(即散列码)要做的第一步是创建 MessageDigest对象 实例。像所有的引擎类一样,获取某类报文摘要算法(即散列算法,比如MD5)的  MessageDigest 对象的途径是调用 MessageDigest 类中的 getInstance 静态 factory 方法:
    
    

        public static MessageDigest getInstance(String algorithm)

    注意:算法名不区分大小写。例如,以下所有调用都是相等的:
    
    

     

    MessageDigest.getInstance("SHA");
    MessageDigest.getInstance("sha");
    MessageDigest.getInstance("sHa");

     

    调用程序可选择指定提供者名称,以保证所要求的算法是由已命名提供者实现的:
    
    

    public static MessageDigest getInstance(String algorithm, String provider);

    调用 getInstance 将返回已初始化过的MessageDigest对象。因此,它不需要进一步的初始化。
    2.2、向MessageDigest传送要计算的数据
    计算数据的摘要的第二步是向已初始化的MessageDigest对象提供传送要计算的数据。这将通过一次或多次调用以下某个 update(更新)方法来完成:
    
    

     

    public void update(byte input);
    public void update(byte[] input);
    public void update(byte[] input, int offset, int len);

     

    2.3、计算摘要
    通过调用 update 方法向MessageDigest对象传送要计算的数据后,你就可以调用以下某个 digest(摘要)方法来计算摘要(即生成散列码):
    
    

     

    public byte[] digest();
    public byte[] digest(byte[] input);
    public int digest(byte[] buf, int offset, int len);

     

    前两个方法返回计算出的摘要。后一个方法把计算出的摘要储存在所提供的 buf 缓冲区中,起点是 offset。len 是 buf 中分配给该摘要的字节数。该方法返回实际存储在 buf 中的字节数。
    对第二个接受输入字节数组变量的 digest 方法的调用等价于用指定的输入调用:
    
    

        public void update(byte[] input)

    ,接着调用不带参数的 digest 方法.

    三、例子演示

    3.1、★ 编程思路:
    java.security包中的MessageDigest类提供了计算消息摘要即生成散列码的方法,首先生成对象,执行其update( )方法可
    以将原始数据传递给该对象,然后执行其digest( )方法即可得到消息摘要。具体步骤如下:
    (1)生成MessageDigest对象
    
    

    MessageDigest m=MessageDigest.getInstance("MD5");

    MessageDigest类也是一个工厂类,其构造器是受保护的,不允许
    直接使用new MessageDigist( )来创建对象,而必须通过其静态方法getInstance( )生成MessageDigest对象
    其中传入的参数指定计算消息摘要所使用的算法,常用的有"MD5","SHA"等。
    (2)传入需要计算的字符串
    
    

    m.update(x.getBytes("UTF8" ));

    分析:x为需要计算的字符串,update传入的参数是字节类型或字节类型数组,对于字符串,需要先使用getBytes( )方法生成字符串数组。
    (3)计算消息摘要
    
    

    byte s[ ]=m.digest( );

    分析:执行MessageDigest对象的digest( )方法完成计算,计算的结果通过字节类型的数组返回。
    (4)处理计算结果
    必要的话可以使用如下代码将计算结果(byte数组)转换为字符串。
    
    

     

    static String convertToHexString(byte data[]) {
    StringBuffer strBuffer = new StringBuffer();
    for (int i = 0; i < data.length; i++) {
    strBuffer.append(Integer.toHexString(0xff & data[i]));
    }
    return strBuffer.toString();
    }

     

    3.2、示例一
    完整程序如下:
    
    

     

    public class MessageDigestDemo extends Thread {
    public void run() {
    String text = "abc";
    byte data[] = null;
    MessageDigest m;
    try {
    data = text.getBytes("UTF8");
    = MessageDigest.getInstance("MD5");
    m.update(data);
    byte resultData[] = m.digest();
    System.out.println(convertToHexString(resultData));
    } catch (NoSuchAlgorithmException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
     
    }
     
    static String convertToHexString(byte data[]) {
    StringBuffer strBuffer = new StringBuffer();
    for (int i = 0; i < data.length; i++) {
    strBuffer.append(Integer.toHexString(0xff & data[i]));
    }
    return strBuffer.toString();
    }
    }

     

    ★运行结果
    
    

    900150983cd24fb0d6963f7d28e17f72

     3.3、示例二
    在这里我们将对计算生成的md5使用 sun.misc.BASE64Encoder进行简单的加密。
    
    

     

        public String md5sumWithEncoder(String text) throws NoSuchAlgorithmException, 
    UnsupportedEncodingException{
            /*确定计算方法*/
            MessageDigest md5=MessageDigest.getInstance("MD5");
            BASE64Encoder base64en = new BASE64Encoder();
            /*加密后的散列码字符串*/
            String strMd5=base64en.encode(md5.digest(text.getBytes("utf-8")));
            return strMd5;
        }

     

    调用函数
    
    

     

    String str="0123456789"
     System.out.printlnmd5sumWithEncoderstr));

     

     输出
    eB5eJF1ptWaXm4bijSPyxw==
     
     
     
     
    构造方法摘要
    protected MessageDigest(String algorithm) 
              创建具有指定算法名称的MessageDigest 实例对象
     
    方法摘要
     Object clone() 
              如果实现是可复制的,则返回一个副本。
     byte[] digest() 
              通过执行诸如填充之类的最终操作完成哈希计算。
     byte[] digest(byte[] input) 
              使用指定的字节数组对摘要进行最后更新,然后完成摘要计算。
     int digest(byte[] buf, int offset, int len) 
              通过执行诸如填充之类的最终操作完成哈希计算。
     String getAlgorithm() 
              返回标识算法的独立于实现细节的字符串。
     int getDigestLength() 
              返回以字节为单位的摘要长度,如果提供程序不支持此操作并且实现是不可复制的,则返回 0。
    static MessageDigest getInstance(String algorithm) 
              生成实现指定摘要算法的 MessageDigest 对象。
    static MessageDigest getInstance(String algorithm, Provider provider) 
              生成实现指定提供程序提供的指定算法的 MessageDigest 对象,如果该算法可从指定的提供程序得到的话。
    static MessageDigest getInstance(String algorithm, String provider) 
              生成实现指定提供程序提供的指定算法的 MessageDigest 对象,如果该算法可从指定的提供程序得到的话。
     Provider getProvider() 
              返回此信息摘要对象的提供程序。
    static boolean isEqual(byte[] digesta, byte[] digestb) 
              比较两个摘要的相等性。
     void reset() 
              重置摘要以供再次使用。
     String toString() 
              返回此信息摘要对象的字符串表示形式。
     void update(byte input) 
              使用指定的字节更新摘要。
     void update(byte[] input) 
              使用指定的字节数组更新摘要。
     void update(byte[] input, int offset, int len) 
              使用指定的字节数组,从指定的偏移量开始更新摘要。
     void update(ByteBuffer input) 
              使用指定的 ByteBuffer 更新摘要。
    二、实际实践
    2.1、创建 MessageDigest 对象
    计算信息摘(即散列码)要做的第一步是创建 MessageDigest对象 实例。像所有的引擎类一样,获取某类报文摘要算法(即散列算法,比如MD5)的  MessageDigest 对象的途径是调用 MessageDigest 类中的 getInstance 静态 factory 方法:
    
    

        public static MessageDigest getInstance(String algorithm)

    注意:算法名不区分大小写。例如,以下所有调用都是相等的:
    
    

     

    MessageDigest.getInstance("SHA");
    MessageDigest.getInstance("sha");
    MessageDigest.getInstance("sHa");

     

    调用程序可选择指定提供者名称,以保证所要求的算法是由已命名提供者实现的:
    
    

    public static MessageDigest getInstance(String algorithm, String provider);

    调用 getInstance 将返回已初始化过的MessageDigest对象。因此,它不需要进一步的初始化。
    2.2、向MessageDigest传送要计算的数据
    计算数据的摘要的第二步是向已初始化的MessageDigest对象提供传送要计算的数据。这将通过一次或多次调用以下某个 update(更新)方法来完成:
    
    

     

    public void update(byte input);
    public void update(byte[] input);
    public void update(byte[] input, int offset, int len);

     

    2.3、计算摘要
    通过调用 update 方法向MessageDigest对象传送要计算的数据后,你就可以调用以下某个 digest(摘要)方法来计算摘要(即生成散列码):
    
    

     

    public byte[] digest();
    public byte[] digest(byte[] input);
    public int digest(byte[] buf, int offset, int len);

     

    前两个方法返回计算出的摘要。后一个方法把计算出的摘要储存在所提供的 buf 缓冲区中,起点是 offset。len 是 buf 中分配给该摘要的字节数。该方法返回实际存储在 buf 中的字节数。
    对第二个接受输入字节数组变量的 digest 方法的调用等价于用指定的输入调用:
    
    

        public void update(byte[] input)

    ,接着调用不带参数的 digest 方法.

    三、例子演示

    3.1、★ 编程思路:
    java.security包中的MessageDigest类提供了计算消息摘要即生成散列码的方法,首先生成对象,执行其update( )方法可
    以将原始数据传递给该对象,然后执行其digest( )方法即可得到消息摘要。具体步骤如下:
    (1)生成MessageDigest对象
    
    

    MessageDigest m=MessageDigest.getInstance("MD5");

    MessageDigest类也是一个工厂类,其构造器是受保护的,不允许
    直接使用new MessageDigist( )来创建对象,而必须通过其静态方法getInstance( )生成MessageDigest对象
    其中传入的参数指定计算消息摘要所使用的算法,常用的有"MD5","SHA"等。
    (2)传入需要计算的字符串
    
    

    m.update(x.getBytes("UTF8" ));

    分析:x为需要计算的字符串,update传入的参数是字节类型或字节类型数组,对于字符串,需要先使用getBytes( )方法生成字符串数组。
    (3)计算消息摘要
    
    

    byte s[ ]=m.digest( );

    分析:执行MessageDigest对象的digest( )方法完成计算,计算的结果通过字节类型的数组返回。
    (4)处理计算结果
    必要的话可以使用如下代码将计算结果(byte数组)转换为字符串。
    
    

     

    static String convertToHexString(byte data[]) {
    StringBuffer strBuffer = new StringBuffer();
    for (int i = 0; i < data.length; i++) {
    strBuffer.append(Integer.toHexString(0xff & data[i]));
    }
    return strBuffer.toString();
    }

     

    3.2、示例一
    完整程序如下:
    
    

     

    public class MessageDigestDemo extends Thread {
    public void run() {
    String text = "abc";
    byte data[] = null;
    MessageDigest m;
    try {
    data = text.getBytes("UTF8");
    = MessageDigest.getInstance("MD5");
    m.update(data);
    byte resultData[] = m.digest();
    System.out.println(convertToHexString(resultData));
    } catch (NoSuchAlgorithmException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
     
    }
     
    static String convertToHexString(byte data[]) {
    StringBuffer strBuffer = new StringBuffer();
    for (int i = 0; i < data.length; i++) {
    strBuffer.append(Integer.toHexString(0xff & data[i]));
    }
    return strBuffer.toString();
    }
    }

     

    ★运行结果
    
    

    900150983cd24fb0d6963f7d28e17f72

     3.3、示例二
    在这里我们将对计算生成的md5使用 sun.misc.BASE64Encoder进行简单的加密。
    
    

     

        public String md5sumWithEncoder(String text) throws NoSuchAlgorithmException, 
    UnsupportedEncodingException{
            /*确定计算方法*/
            MessageDigest md5=MessageDigest.getInstance("MD5");
            BASE64Encoder base64en = new BASE64Encoder();
            /*加密后的散列码字符串*/
            String strMd5=base64en.encode(md5.digest(text.getBytes("utf-8")));
            return strMd5;
        }

     

    调用函数
    
    

     

    String str="0123456789"
     System.out.printlnmd5sumWithEncoderstr));

     

     输出
    eB5eJF1ptWaXm4bijSPyxw==
  • 相关阅读:
    Django项目的docker镜像制作
    可爱猫+python——定制化微信机器人
    django环境搭建遇到的问题
    python学习日记——利用python进行数据分析
    python学习日记——django基础
    bug字典整理
    Mysql字典收集
    MySQL开放第三方主机访问权限
    python学习日记——httprunner
    vux swiper 自定义高度
  • 原文地址:https://www.cnblogs.com/liuyangv/p/8179790.html
Copyright © 2020-2023  润新知