Java Two-dimensional code login process implementation code

Source: Internet
Author: User
Tags bitwise md5 unique id

In recent years, the use of two-dimensional code more and more wind, the author recently on hand also encountered a need to use two-dimensional code to scan the site's live, so the study of this set of mechanisms, and code to achieve the entire process, and then we chat about two-dimensional code login and those things.

Two-dimensional code principle

Two-dimensional code is a micro-letter to get up, the same year micro-scan code two-dimensional code to login to the Web site micro-letter, the feeling is very magical, however, we understand its principle, it is not so magical. The two-dimensional code actually contains a URL request information through a black and white dot matrix. Sweep code on the end, request URL, do the corresponding operation.

Principle of general sweep code operation

Micro-letter login, pay treasure Sweep code payment is this principle:

1. Request two dimensional code

The desktop side initiates a request for a two-dimensional code to the server.

2. Generate a two-dimensional code that contains a unique ID

The desktop side randomly generates a id,id that uniquely identifies the two-dimensional code for subsequent operations.

3. Sweep code on end

Moving end-sweep code two-dimensional code, the solution Chu out of two-dimensional code in the URL request.

4. Mobile end Send request to server

The mobile end sends a URL request to the server, which contains two information, which code is scanned by the unique ID identifier, and the specific cookie or header parameter in the browser will be identified by which user to sweep the code.

Description: The core code is not original, draw on the code of others, thanks!

5. Server-side notification sweep code success

When the server receives the URL request of the information in the two-dimensional code, the notification side has already swept the code successfully, and adds the necessary information such as the login cookie. There are generally a few ways to notify: WebSocket, rotation hold to live the request until the timeout, a few seconds rotation.

The art of URL in two-dimensional code

How to achieve the different performance of own client and other client scan code (such as micro-letter)

For example, in a business, you might want to do this, if your company's two-dimensional code is scanned by other apps (such as micro-mail), you want to jump to a hint page, you can have an app download link on the page, and then respond directly to the request when scanned by your own app.

In this case, you can do this, all the links in the two-dimensional code are encrypted one layer, and then unified with another link to deal with.

such as: Www.test.com/qr?p=xxxxxx,p parameter contains the server and the client agreed to add decryption algorithm (can be symmetrical or asymmetric), the end of the sweep code to this particular path, directly with the decryption algorithm to solve p parameters, get www.testqr.com/ Qrcode?key=s1arv, so that you can initiate a request to the server, and other clients because they do not know this rule, can only go directly to request WWW.TEST.COM/QR?P=XXXXXX, the request returned to the prompt page.

How to make a two-dimensional code simpler

A lot of times, and the horse run, cake. If you want a two-dimensional code with a lot of parameters, but do not want the two-dimensional code too complex, difficult to be swept out of the code. At this point, you need to consider how to make the two-dimensional code simpler without impacting the business.

    • With the end of the Convention rules: for example, the definition of encoding information in the I parameter to 1,2,3 represents a different URI, the end of the match encountered a different I parameters to request which interface

    • Simplify everything to simplify: Simplify the URI, simplify the key in the parameter, value. such as Www.a.com/q?k=s1arV is much simpler than www.abc.def.adfg.edu.com.cn/qrcode/scan?k=77179574e98a7c860007df62a5dbd98b, The resulting two-dimensional code is much better swept.

    • Simplify unique ID parameter: The parameter value in the previous request in the previous one is only 5 bits, and the parameter value in the last request is the generated 32-bit MD5 value. It is important to generate one-side key.

Sample code

Generate two-dimensional code (remove white edges, increase the logo in the middle)

Need to import jar package: Zxing Core-2.0.jar

The code is as follows Copy Code

import java.awt.basicstroke;
import java.awt.color;
import java.awt.graphics;
import java.awt.graphics2d;
import java.awt.image;
import java.awt.shape;
import java.awt.geom.roundrectangle2d;
import java.awt.image.bufferedimage;
import java.io.bytearrayoutputstream;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.util.hashmap;

import java.util.map;
import javax.imageio.imageio;
import com.google.zxing.barcodeformat;
import com.google.zxing.encodehinttype;
import com.google.zxing.multiformatwriter;
import com.google.zxing.common.bitmatrix;

import com.google.zxing.qrcode.decoder.errorcorrectionlevel; public class qrcodeutil {  private static final int black =
 color.black.getrgb ();
  private static final int white = color.white.getrgb ();   private static final int default_qr_size = 183;
  private static final String DEFAULT_QR_FORMAT =  "PNG";
  private static final byte[] EMPTY_BYTES = new byte[0];      public static byte[] createqrcode (string content, int  size, string extension)  {    return createqrcode (Content, size,
 extension, null); &NBSP;&NBSP}   /**    *  generation of two-dimensional code    *  @param  content with pictures   information to include in two-dimensional code    *  @param  size  size    *  @param   extension  file format extension    *  @param  insertImg  middle logo picture    * @ Return    */  public static byte[] createqrcode (String content,  int size, string extension, image inseRTIMG)  {    if  (size <= 0)  {       throw new illegalargumentexception ("size " (" + size + ")  cannot
 be <= 0 ");
    }     ByteArrayOutputStream baos = null;     try {      Map hints = new 
HashMap ();
      hints.put (encodehinttype.character_set,  "Utf-8");

      hints.put (ENCODEHINTTYPE.ERROR_CORRECTION,&NBSP;ERRORCORRECTIONLEVEL.M);       //uses information to generate a bitmap of the specified size       bitmatrix m =  new multiformatwriter (). Encode (content, barcodeformat.qr_code, size, size, 
hints);              //remove white edge       m = updatebit (m, 0);              int width = m.getwidth (
);
      int height = m.getheight ();              //Sets the information in Bitmatrix to Bufferdimage. Form Black-and-White picture       bufferedimage image = new bufferedimage (width,
&NBSP;HEIGHT,&NBSP;BUFFEREDIMAGE.TYPE_INT_RGB);       for  (int i = 0; i < width; i++)  {        for  (int j = 0; j <  height; j++)  {          image.setrgb (i,
 j, m.get (I,&NBSP;J)  ? black : white);         }       }       if  (insertimg != null)  {        //   Insert logo picture         insertimage in the middle (image, insertimg, 
M.getwidth ()); &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP}       //will be enlarged by a picture that is smaller for white edges    
   image = zoominimage (image, size, size);
      baos = new bytearrayoutputstream ();
      imageio.write (Image, extension, baos);
             return baos.tobytearray ();     } catch  (exception e)  {    } finally  {      if (baos != null)          try {          baos.cloSE ();         } catch  (ioexception e)  {           // todo auto-generated catch block  
         e.printstacktrace ();         }          return 
Empty_bytes; &NBSP;&NBSP}      /**    *  Custom two-dimensional code white-side width    *  @param
 matrix    *  @param  margin    *  @return    */   private static bitmatrix updatebit (Bitmatrix matrix, int margin)  {    int tempM = margin * 2;     int[]  rec = matrix.getenclosingrectangle (); //  Gets the properties of a two-dimensional code pattern     int  Reswidth = rec[2] + tempm;
    int resHeight = rec[3] + tempM;     bitmatrix resmatrix = new bitmatrix (ResWidth, resHeight);
 //  generate a new Bitmatrix     resmatrix.clear () according to the custom border;     for  (int i = margin; i < reswidth -  margin; i++)  { //  loop, drawing two-dimensional code patterns into the new Bitmatrix       for  ( int j = margin; j < resheight - margin; j++)  {         if  (Matrix.get (i - margin + rec[0], j &NBSP;-&NBSP;MARGIN&NBSP;+&NBSP;REC[1])  {          
Resmatrix.set (I,&NBSP;J);         }             }     return resMatrix; &NBSP;&NBSP}      //  picture zoom Out   public static BufferedImage  Zoominimage (bufferedimage originalimage, int width, int height)  {     bufferedimage newimage = new bufferedimage (width, height, 
Originalimage.gettype ());
    graphics g = newimage.getgraphics ();
    g.drawimage (Originalimage, 0, 0, width, height, null);
    g.dispose ();
    return newImage; &NBSP;&NBSP}      private static void insertimage (Bufferedimage source,  image insertimg, int size)  {    try {   
   int width = insertimg.getwidth (NULL);
      int height = insertimg.getheight (NULL); &nbsP;     width = width > size / 6 ? size  / 6 : width; // logo is set to a two-dimensional code of one-sixth size       height
 = height > size / 6 ? size / 6 : height;
      graphics2d graph = source.creategraphics ();
      int x =  (size - width)  / 2;
      int y =  (size - height)  / 2;       graph.drawimage (insertimg, x, y, width, height, 
NULL);       shape shape = new roundrectangle2d.float (X, y,
&NBSP;WIDTH,&NBSP;WIDTH,&NBSP;6,&NBSP;6);
      graph.setstroke (New basicstroke (3f));       graph.draW (shape);
      graph.dispose ();     } catch  (exception e)  {      
E.printstacktrace (); &NBSP;&NBSP;&NBSP;&NBSP}   }   public static byte[] createqrcode (String  content)  {    return createqrcode (content, default_qr_size, 
Default_qr_format); &NBSP;&NBSP}   public static void main (String[] args) {     try {      fileoutputstream fos = new fileoutputstream (
"Ab.png");
      fos.write (Createqrcode ("Test"));
      fos.close ();     } catch  (exception e)  {      //
 todo auto-generated catch block       e.printstacktrace ();     }        }   } 

Generate Short Links

Basic ideas:

The theory of short URL mapping algorithm:

1. The long web site plus random number with the MD5 algorithm to generate 32-bit signature string, divided into 4 paragraphs, 8 characters per paragraph

2. For the 4-segment loop, take 8 characters per paragraph and consider him as a bit of the 16-in-string and 0X3FFFFFFF (30-bit 1) with operations, over 30-bit ignore processing

3. The 30 bits obtained in each paragraph are divided into 6 segments, each 5 digit number is taken as the index of the alphabet to obtain a specific character and the 6-bit string is obtained sequentially;

4. Such a MD5 string can be obtained from 4 6-bit strings, whichever of them can be used as the short URL of this long URL.

5. It is best to use a Key-value database storage, in case of collision for one, if four have collided, regenerate MD5 (because there are random numbers, will generate a different MD5)

The code is as follows Copy Code
public class shorturlutil {  /**    *  incoming 32-bit MD5 value    *   @param  md5    *  @return    */  public static  String[] shorturl (STRING&NBSP;MD5)  {    //  characters to use build  URL       String[] chars = new String[] {  "A",  "B",  "C",  "D",  "E",  "F",  "G",  "H",          "I",  "J",   "K",  "L",  "M",  "n",  "O",  "P",  "Q",  "R",  "s",  "T",           "U",  "V",  "W",  "x",  "y",  "z",  "0",   "1",  "2",  "3",  "4",  "5",          "6",  "7" ", " 8 ", " 9 ", " A ", " B ", " C ", " D ", " E ", " F ", " G ", " H ",           "I",  "J",  "K",  "L",  "M",  "N",  "O",  "P",  "Q" ,  "R",  "S",  "T",          "U",  "V",  "W",  "
X ", " Y ", " Z "    };
         String[] resUrl = new String[4];           for  (int i = 0; i < 4;  i++)  {      //  put encrypted characters in  8  bit by a set of  16  system and   0x3fffffff  bit and operation, over 30-bit ignore       String sTempSubString = 

Md5.substring (I&NBSP;*&NBSP;8,&NBSP;I&NBSP;*&NBSP;8&NBSP;+&NBSP;8);       //  need to use the  long  type to convert, because  inteper .parseint ()   Can only handle  31  bit  ,  first for symbol bit  ,  if not  long   long lhexlong = 0x3fffffff & long.parselong (STEMPSUBSTRING,&NBSP;16);
      String outChars =  "";       for  (int j = 0; j < 6; j++)  {        //  put the obtained value and  0x0000003D  to the bitwise AND operation, get the character array   chars  Index         long index = 0x0000003D &
 lHexLong;         //  adds the acquired characters        
 outchars += chars[(int)  index];         //  per loop bitwise right  5  bit      
   lHexLong = lHexLong >> 5; &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP}       //  the output array that stores the string to the corresponding index        resUrl[i] = outchars;
    }     return resUrl; &NBSP;&NBSP}      public static void main (String [] args) { 
   string[] test = shorturl ("Fdf8d941f23680be79af83f921b107ac");     for  (string string : test)  {     
 system.out.println (string);     }  &nbsp}   }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.