Nos últimos anos, o uso de códigos QR se tornou cada vez mais próspero. Recentemente, encontrei um trabalho que exige que o código QR faça login no site. Então, estudei esse mecanismo e implementei todo o processo com o código. Em seguida, falarei com você sobre o login de código QR e outras coisas.
O princípio do código QR
O código QR foi criado pelo WeChat. Quando examinamos o código QR no WeChat, nos sentimos muito mágicos quando entramos na página da Web do WeChat. No entanto, depois de entendermos seus princípios, não é tão mágico. O código QR realmente contém informações de solicitação de URL através de uma matriz de pontos em preto e branco. Digitalize o código no terminal, solicite o URL e faça a operação correspondente.
O princípio da operação geral de varredura de código
Este é o princípio do WeChat Login e Alipay Scanning Code Payment:
1. Solicite um código QR
O desktop inicia uma solicitação de código QR ao servidor.
2. Gere um código QR com um ID exclusivo
A área de trabalho gerará aleatoriamente um ID e o ID identificará exclusivamente esse código QR para operações subsequentes.
3. Digitalize o código na placa
Digitalize o código QR no terminal móvel para resolver a solicitação de URL no código QR.
4. O terminal móvel envia uma solicitação para o servidor
O terminal móvel envia uma solicitação de URL ao servidor, que contém duas informações. O ID exclusivo identifica qual código é digitalizado e os parâmetros específicos de cookie ou cabeçalho no navegador no terminal identificarão quais usuários digitalizam o código.
5. Notificação do lado do servidor para digitalizar o código com sucesso
Quando o servidor recebe a solicitação de URL para as informações no código QR, o lado da notificação digitalizou com sucesso o código e adicionou os cookies de login necessários e outras informações. Geralmente, existem vários métodos de notificação aqui: WebSocket, o treinamento de retenção até o tempo limite e o treinamento leva vários segundos.
A arte do URL no código QR
Como perceber a diferença entre os códigos de digitalização (como o WeChat) entre seu próprio cliente e outro cliente
Por exemplo, nos negócios, você pode querer fazer isso. Se o código QR da sua empresa for digitalizado por outros aplicativos (como o WeChat) e você quiser pular para uma página rápida, pode haver um link de download de aplicativos na página Prompt; E quando for digitalizado pelo seu próprio aplicativo, faça a solicitação correspondente diretamente.
Nesse caso, isso pode ser feito, todos os links no código QR são criptografados em uma camada e depois tratados com outro link.
Por exemplo: www.test.com/qr?p=xxxxxx, o parâmetro P contém o algoritmo de criptografia e descriptografia acordado pelo servidor e pelo cliente (pode ser simétrico ou assimétrico). Ao digitalizar o código no terminal para esse caminho específico, o parâmetro P é usado diretamente para resolver o parâmetro P e obter www.testqr.com/qrcode?key=s1arv, para que a solicitação possa ser iniciada para o servidor. Como outros clientes não conhecem essa regra, eles só podem solicitar diretamente www.test.com/qr?p=xxxxxx. Esta solicitação retorna à página prompt.
Como simplificar o código QR
Muitas vezes, os cavalos são convidados a correr e não comer grama. Quero que o código QR tenha muitos parâmetros, mas não quero que o código QR seja muito complicado e é difícil digitalizar o código. No momento, você precisa considerar como simplificar o código QR sem afetar os negócios.
Código de amostra
Gere código QR (remova as bordas brancas e adicione o logotipo do meio)
Precisa importar o pacote JAR: Core-2.0.jar de Zxing
importar java.awt.basicstoke; importar java.awt.color; importar java.awt.graphics; importar java.awt.graphics2d; importar java.awt.IMAFED; java.io.byteArrayOutputStream; importar java.io.fileOutputStream; importar java.io.ioException; importar java.util.hashmap; importar java.util.map; importatykmatiat.imageio.imageio; import.google.zxing.Barcformat; com.google.zxing.multiformatwriter; importar com.google.zxing.common.bitmatrix; importar com.google.zxing.qrcode.decoder.errorCorrectionLevel; classe pública Qrcodeutil {private static final int = color.black.getRgb (); private estático final int branco = color.white.getRgb (); private estático final int default_qr_size = 183; String final estática privada default_qr_format = "png"; byte final estático final privado [] email_bytes = novo byte [0]; public static byte [] createqrcode (conteúdo da string, tamanho int, extensão de string) {return createqrcode (conteúdo, tamanho, extensão, nulo); } / *** Gere um código QR com uma imagem* @param Informações de conteúdo a serem incluídas no código QR* @param tamanho do tamanho* @param Extensão Extensão do arquivo de extensão* @param insertimg o logotipo do meio imagem* @return* / public static byte [] createqrcode (tamanho da string, tamanho da string, string {strate insertim) {ifng (] size (size (tamanho da string) @return* stratg byte (size (size (size) (tamanho de string) @return* stratg byte [] createqrcode (tamanho da string, tamanho da string, string, imagem* (" + tamanho +") não pode ser <= 0 "); } ByteArrayOutputStream baos = null; tente {map <EncodeHintType, objeto> Hints = new HashMap <EncodeHIntType, object> (); Hints.put (codehinttype.character_set, "utf-8"); Hints.put (codehinttype.error_correction, errorCorrectionLevel.m); // Use as informações para gerar uma matriz de pontos de tamanho especificado BitMatrix M = new MultiformatWriter (). Encode (conteúdo, BarcodeFormat.qr_code, tamanho, tamanho, dicas); // Remova a borda branca m = updatebit (m, 0); int width = m.getWidth (); int altura = m.getheight (); // Defina as informações no BitMatrix na imagem buffer para formar uma imagem de bufferImage em preto e branco na imagem = new bufferImage (largura, altura, bufferImage.type_int_rgb); para (int i = 0; i <largura; i ++) {for (int j = 0; j <altura; j ++) {image.setrgb (i, j, m.get (i, j)? preto: branco); }} if (insertImg! = null) {// Insira a inserção da imagem do logotipo do meio (imagem, insertImg, m.getWidth ()); } // Aumentar a imagem que se torna menor devido à remoção da imagem da borda branca = ZoomInimage (imagem, tamanho, tamanho); baos = novo bytearrayOutputStream (); Imageio.write (imagem, extensão, baos); retornar baos.tobytearray (); } catch (Exceção e) {} finalmente {if (baos! = null) tente {baos.close (); } catch (ioexception e) {// TODO GATO GENERADO AUTOMENTADO BLOCO E.PRINTSTACKTRACE (); }} retornar empty_bytes; } / * * int [] rec = matrix.getEnclosingRectangle (); // Obtenha o atributo do padrão de código QR int reswidth = rec [2] + tempm; int resheight = rec [3] + tempm; BitMatrix resmatrix = new BitMatrix (resWidth, remetente); // gerar novos bitmatrix resmatrix.clear () de acordo com a borda personalizada; para (int i = margem; i <resWidth - margem; i ++) {// loop para desenhar o padrão de código QR para a nova bitmatrix para (int j = margem; j <ressenseight - margin; j ++) {if (matrix.get (i -+margin [0], j - margin+rec [1]) {(1] {{RESCET (i -set (i -+rec [0], j -margin+rec [1]; }} retornar resmatrix; } // Imagem Zoom dentro e fora do zoominImage public estática public (bufferImage OriginalImage, int Warth, int altura) {bufferEdImage newImage = new bufferImage (largura, altura, originalImage.getType ()); Gráficos g = newImage.getGraphics (); G.Drawimage (OriginalImage, 0, 0, largura, altura, nulo); G.Dispose (); retornar newImage; } private estático void insertImage (fonte de bufferImage, insertImg de imagem, int size) {try {int width = insertImg.getWidth (null); int height = insertImg.getHeight (nulo); largura = largura> tamanho / 6? tamanho / 6: largura; // Defina o logotipo como um sexto do tamanho da altura do código QR = altura> tamanho / 6? tamanho / 6: altura; Graphics2D Graph = Source.CreateGraphics (); int x = (tamanho - largura) / 2; int y = (tamanho - altura) / 2; Graph.Drawimage (insertimg, x, y, largura, altura, nulo); Forma da forma = novo RoundRectangle2d.float (x, y, largura, largura, 6, 6); Graph.SetStroke (novo BasicStroke (3F)); Graph.Draw (Shape); graf.dispose (); } catch (Exceção 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 ("teste")); fos.close (); } Catch (Exceção e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); }}}Gerar links curtos
Ideias básicas:
A teoria do algoritmo de mapeamento de URL curto:
1. Use o algoritmo MD5 para gerar uma sequência de assinatura de 32 bits, dividida em 4 segmentos, cada segmento com 8 caracteres.
2. Para esses 4 segmentos, tome 8 caracteres em cada segmento, trate -o como um pouco e operação da corda hexadecimal e 0x3ffffffff (30 bits 1) e ignore o processamento de mais de 30 bits.
3. Divida os 30 dígitos obtidos em cada segmento em 6 segmentos, e cada número de 5 dígitos é usado como o índice do alfabeto para obter caracteres específicos e obter uma corda de 6 bits;
4. Essa sequência MD5 pode obter 4 seqüências de 6 bits, e qualquer uma delas pode ser usada como o endereço de URL curto deste URL longo.
5. É melhor usar um banco de dados de valor-chave para armazená-lo. Em caso de colisão, substitua um. Se todos os quatro colidirem, regenerar o MD5 (porque existem números aleatórios, o MD5 diferente será gerado)
public class Shorturlutil { / ** * Passe no valor MD5 de 32 bits * @param md5 * @return * / public static string [] Shorturl (String md5) {// para usar o caractere que gera o URL String [] chars = new String [] {"A" "B", "C", "D" "" "", ",", ",", ",", ",", ", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "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 [] ressurl = new string [4]; for (int i = 0; i <4; i ++) {// Coloque os caracteres criptografados como 8 bits são um conjunto de hexadecimal e 0x3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff. Se mais de 30 bits forem ignorados String stempsubstring = md5.Substring (i * 8, i * 8 + 8); // Você precisa usar o tipo longo para converter aqui, porque o Inteper .ParseInt () pode processar apenas 31 bits, e o primeiro bit é o bit de sinal. Se você não usar muito, ele ficará fora dos limites de longa data = 0x3fffffff & long.parselong (Stempsubstring, 16); String Outchars = ""; for (int j = 0; j <6; j ++) {// Faça o valor obtido com 0x000003D Execute o bit e a operação para obter o índice de longa matriz de caracteres Índice longo = 0x0000003d & lhexlong; // Adicione os caracteres obtidos supers += chars [(int) índice]; // Cada loop é deslocado de bits deslocado por 5 bits lhexlong = lhexlong >> 5; } // Salvar a sequência na matriz de saída do índice correspondente ressurl [i] = outchars; } retornar ressurl; } public static void main (string [] args) {string [] test = shorturl ("fdf8d941f23680be79af83f921b107ac"); para (String String: test) {System.out.println (String); }}} Nota: O código principal não é original e empresta do código de outras pessoas, obrigado!
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.