En los últimos años, el uso de códigos QR se ha vuelto cada vez más próspero. Recientemente, he encontrado un trabajo que requiere escanear el código QR para iniciar sesión en el sitio web. Así que he estudiado este mecanismo e implementé todo el proceso con el código. A continuación, hablaré con usted sobre el inicio de sesión del código QR y otras cosas.
El principio del código QR
El código QR fue creado por WeChat. Cuando escaneamos el código QR en WeChat, nos sentimos muy mágicos cuando iniciamos sesión en la página web de WeChat. Sin embargo, después de que entendemos sus principios, no es tan mágico. El código QR en realidad contiene información de solicitud de URL a través de una matriz de puntos en blanco y negro. Escanee el código en el terminal, solicite la URL y realice la operación correspondiente.
El principio de la operación de escaneo de código general
Este es el principio del pago del código de escaneo de WeChat y Alipay: Pago:
1. Solicite un código QR
El escritorio inicia una solicitud de código QR al servidor.
2. Generar un código QR con una ID única
El escritorio generará aleatoriamente una ID, y la ID identificará de forma exclusiva este código QR para operaciones posteriores.
3. Escanee el código en el tablero
Escanee el código QR en el terminal móvil para resolver la solicitud de URL en el código QR.
4. El terminal móvil envía una solicitud al servidor
El terminal móvil envía una solicitud de URL al servidor, que contiene dos información. La identificación única identifica qué código se escanea, y los parámetros específicos de cookie o encabezado en el navegador en el terminal identificarán qué usuario escanear el código.
5. Notificación del lado del servidor para escanear el código correctamente
Cuando el servidor recibe la solicitud de URL para la información en el código QR, el lado de la notificación ha escaneado con éxito el código y ha agregado las cookies de inicio de sesión necesarias y otra información. En general, hay varios métodos de notificación aquí: WebSocket, solicitud de retención de capacitación hasta el tiempo de espera y la capacitación tarda varios segundos.
El arte de la URL en el código QR
Cómo realizar la diferencia entre los códigos de escaneo (como WeChat) entre su propio cliente y otro cliente
Por ejemplo, en los negocios, es posible que desee hacer esto. Si otras aplicaciones escanean el código QR de su empresa (como WeChat), y desea saltar a una página de inmediato, puede haber un enlace de descarga de la aplicación en la página de solicitud; Y cuando sea escaneada por su propia aplicación, haga la solicitud correspondiente directamente.
En este caso, esto se puede hacer, todos los enlaces en el código QR están encriptados en una capa y luego se manejan con otro enlace.
Por ejemplo: www.test.com/qr?p=xxxxxx, el parámetro P contiene el algoritmo de cifrado y descifrado acordado por el servidor y el cliente (puede ser simétrico o asimétrico). Al escanear el código en el terminal a esta ruta específica, el parámetro P se usa directamente para resolver el parámetro P y obtener www.testqr.com/qrcode?key=s1arv, de modo que la solicitud se pueda iniciar al servidor. Debido a que otros clientes no conocen esta regla, solo pueden solicitar directamente www.test.com/qr?p=xxxxxx. Esta solicitud vuelve a la página de solicitud.
Cómo hacer que el código QR sea más simple
Muchas veces, se les pide a los caballos que corran y no coman hierba. Quiero que el código QR tenga muchos parámetros, pero no quiero que el código QR sea demasiado complicado y es difícil escanear el código. En este momento, debe considerar cómo simplificar el código QR sin afectar el negocio.
Código de muestra
Genere el código QR (retire los bordes blancos y agregue el logotipo central)
Necesito importar el paquete JAR: Core-2.0.0. Jar de Zxing
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; java.io.bytearRaRyOutputStream; 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.zxxing.engodehodePe; com.google.zxing.multiformatwriter; import com.google.zxing.common.bitmatrix; import com.google.zxing.qrcode.decoder.errorcorrectionLevel; clase pública qrcodeutil {private static int black = color.black.getrgb (); Private static final int white = color.white.getRgb (); privado estático final int default_qr_size = 183; Cadena final estática privada default_qr_format = "png"; Private estático final final final byte [] vacía_bytes = nuevo byte [0]; public static byte [] createqrcode (contenido de cadena, intize int, extensión de cadena) {return createQRCode (contenido, tamaño, extensión, nulo); } / *** Genere un código QR con una imagen* @param información de contenido que se incluya en el código QR* @param tamaño tamaño* @param extensión formato de archivo extensión* @param insertimg la imagen del logotipo central* @return* / public static byte [] createqrcode (string content, int tamize, string extension, imagen inserTimg) {if (tamaño <= 0) {droga nuevo " tamaño + ") no puede ser <= 0"); } BytearRayOutputStream baos = null; Pruebe {map <codenodeHintType, object> sugerencias = new HashMap <CodeDintType, Object> (); hints.put (encodeHintType.character_set, "UTF-8"); hints.put (encodeHintType.error_correction, errorcorrectionLevel.m); // Use información para generar una matriz de puntos del tamaño especificado BitMatrix M = new MultiformAtWriter (). Code (content, BarcodeFormat.qr_code, tamaño, tamaño, sugerencias); // eliminar el borde blanco m = updateBit (m, 0); int ancho = m.getWidth (); int altura = m.getheight (); // Establezca la información en BitMatrix en Bufferdimage para formar una imagen de imagen en blanco y negro BufferedImage = new BufferedImage (ancho, altura, bufferedimage.type_int_rgb); para (int i = 0; i <width; i ++) {for (int j = 0; j <altura; j ++) {image.setrgb (i, j, m.get (i, j)? negro: blanco); }} if (insertimg! = null) {// inserta la imagen del logotipo central insertimage (imagen, insertimg, m.getWidth ()); } // Ampliar la imagen que se ha vuelto más pequeña debido a la eliminación de la imagen del borde blanco = ZoomInimage (imagen, tamaño, tamaño); baos = new byteArRaReOutputStream (); Imageio.write (imagen, extensión, baos); return baos.tobytearray (); } capt (excepción e) {} finalmente {if (baos! = null) try {baos.close (); } Catch (ioException e) {// tODO Auto Generated BLOCK E.PrintStackTRace (); }} return vacía_bytes; } / ** * Código QR personalizado Ancho de borde blanco * @param matriz * @param margin * @return * / private static bitmatrix updateBit (bitmatrix matrix, int margin) {int tempm = margin * 2; int [] rec = matrix.getEnCLoseRRectAngle (); // Obtener el atributo del patrón de código QR int reswidth = rec [2] + tempm; int consheight = rec [3] + tempm; Bitmatrix resmatrix = new BitMatrix (reswidth, refleight); // Generar una nueva BitMatrix resmatrix.Clear () según el borde personalizado; for (int i = margin; i <reswidth - margin; i ++) {// bucle para dibujar el patrón de código QR en la nueva bitmatrix para (int j = margin; j <resheight - margin; j ++) {if (matrix.get (i - margin+rec [0], j - margen+rec [1])) {resmatrix.set (i, j); }} return resmatrix; } // La imagen amplía y sale pública Static BufferedImage Zoominimage (BufferedImage OriginalImage, int Ancho, int Height) {BufferedImage NewImage = new BufferedImage (ancho, altura, originalimage.gettype ()); Gráficos g = newimage.getGraphics (); G.DrawImage (OriginalImage, 0, 0, ancho, altura, nulo); G.Dispose (); devolver newimage; } privado void static inserTImage (fuente de BufferedImage, imagen insertimg, int tize) {try {int width = insertiMg.getWidth (null); int hight = insertimg.getheight (nulo); ancho = ancho> tamaño / 6? tamaño / 6: ancho; // Establecer el logotipo en un sexto del tamaño del código QR altura = altura> tamaño / 6? tamaño / 6: altura; Graphics2d Graph = Source.CreateGraphics (); int x = (tamaño - ancho) / 2; int y = (tamaño - altura) / 2; gráfico. Forma forma = nuevo Roundrectangle2d.float (x, y, ancho, ancho, 6, 6); Graph.SetStroke (nuevo BasicStroke (3F)); Graph.draw (forma); Graph.Dispose (); } catch (Exception e) {E.PrintStackTrace (); }} public static byte [] createqrcode (string content) {return createQRCode (content, default_qr_size, default_qr_format); } public static void main (string [] args) {try {fileOutputStream fos = new FileOutputStream ("AB.PNG"); fos.write (createQRCode ("test")); fos.close (); } Catch (Exception e) {// TODO Auto Generado Bloque E.PrintStackTrace (); }}}Generar enlaces cortos
Ideas básicas:
La teoría del algoritmo de mapeo de URL corto:
1. Use el algoritmo MD5 para generar una cadena de firma de 32 bits, dividida en 4 segmentos, cada segmento con 8 caracteres.
2. Para estos 4 segmentos, tome 8 caracteres en cada segmento, trátelo como un poco y la operación de una cadena hexadecimal y 0x3ffffffff (30 bit 1), e ignore el procesamiento de más de 30 bits.
3. Divida los 30 dígitos obtenidos en cada segmento en 6 segmentos, y obtenga caracteres específicos como índice del alfabeto, y obtenga cadenas de 6 bits a su vez;
4. Tal cadena MD5 puede obtener 4 cadenas de 6 bits, y cualquiera de ellas puede usarse como la dirección de URL corta de esta larga URL.
5. Es mejor usar una base de datos de valor clave para almacenarla. En caso de colisión, reemplace uno. Si los cuatro chocan, regenere MD5 (porque hay números aleatorios, se generará diferentes MD5)
public class ShortUrlUtil { /** * Pass in 32-bit md5 value* @param md5 * @return */ public static String[] shortUrl(String md5) { // To use the character that generates the 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", "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" "; Cadena [] resurl = nueva cadena [4]; para (int i = 0; i <4; i ++) {// Ponga los caracteres encriptados ya que 8 bits son un conjunto de hexadecimales y 0x3ffffffffffff y realizar bit y cálculos. Si se ignoran más de 30 bits de cadena StemppSubstring = MD5.Substring (i * 8, i * 8 + 8); // Debe usar el tipo largo para convertir aquí, porque Inteper .ParseInt () solo puede procesar 31 bits, y el primer bit es el bit de signo. Si no usa mucho, estará fuera de los límites lhexlong = 0x3ffffff & long.parselong (StemppSubstring, 16); Cadena Outchars = ""; para (int j = 0; j <6; j ++) {// Haga el valor obtenido con 0x000003D BIT y operación para obtener el índice de matriz de caracteres índice largo = 0x0000003d & lhexlong; // Agregar los caracteres obtenidos Outchars += Chars [(int) índice]; // Cada bucle se desplaza por derecha de bits por 5 bits lhexlong = lhexlong >> 5; } // Guarde la cadena en la matriz de salida del índice correspondiente resurl [i] = Outchars; } return reurl; } public static void main (string [] args) {string [] test = shorturl ("fdf8d941f23680be79af83f921b10ac"); for (cadena String: test) {System.out.println (String); }}} Nota: El código central no es original y toma prestado del código de otras personas, ¡gracias!
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.