Ces dernières années, l'utilisation des codes QR est devenue de plus en plus prospère. Récemment, j'ai rencontré un travail qui nécessite la numérisation du code QR pour se connecter au site Web. J'ai donc étudié ce mécanisme et mis en œuvre l'intégralité du processus avec le code. Ensuite, je vous parlerai de la connexion du code QR et d'autres choses.
Le principe du code QR
Le code QR a été créé par WeChat. Lorsque nous scannons le code QR sur WeChat, nous nous sommes sentis très magiques lorsque nous nous sommes connectés à la page Web de WeChat. Cependant, après avoir compris ses principes, ce n'est pas si magique. Le code QR contient en fait une information de demande d'URL via une matrice de points noir et blanc. Scannez le code sur le terminal, demandez l'URL et effectuez l'opération correspondante.
Le principe de l'opération de balayage de code général
Ceci est le principe de la connexion WeChat et du paiement du code de numérisation Alipay:
1. Demande un code QR
Le bureau initie une demande de code QR au serveur.
2. Générez un code QR avec un ID unique
Le bureau générera au hasard un ID et l'ID identifiera de manière unique ce code QR pour les opérations ultérieures.
3. Analyser le code sur la carte
Scannez le code QR sur le terminal mobile pour résoudre la demande d'URL dans le code QR.
4. Le terminal mobile envoie une demande au serveur
Le terminal mobile envoie une demande d'URL au serveur, qui contient deux informations. L'ID unique identifie le code scanné, et les paramètres spécifiques des cookies ou de l'en-tête du navigateur sur le terminal identifieront quel utilisateur analyse le code.
5. Notification côté serveur pour scanner le code avec succès
Lorsque le serveur reçoit la demande URL pour les informations du code QR, le côté notification a réussi à analyser le code et à ajouter les cookies de connexion nécessaires et d'autres informations. Il existe généralement plusieurs méthodes de notification ici: WebSocket, la demande de formation jusqu'au temps mort et la formation prend plusieurs secondes.
L'art de l'URL dans le code QR
Comment réaliser la différence entre les codes de numérisation (tels que WeChat) entre votre propre client et un autre client
Par exemple, dans les affaires, vous voudrez peut-être le faire. Si le code QR de votre entreprise est analysé par d'autres applications (telles que WeChat) et que vous souhaitez passer à une page d'invite, il peut y avoir un lien de téléchargement d'applications sur la page de l'invite; Et lorsqu'il est analysé par votre propre application, faites directement la demande correspondante.
Dans ce cas, cela peut être fait, tous les liens du code QR sont chiffrés en une couche, puis gérés avec un autre lien.
Par exemple: www.test.com/qr?p=xxxxxx, le paramètre P contient l'algorithme de chiffrement et de décryptage convenu par le serveur et le client (peut être symétrique ou asymétrique). Lors de la numérisation du code sur le terminal sur ce chemin spécifique, le paramètre P est directement utilisé pour résoudre le paramètre P et obtenir www.testqr.com/qrcode?key=s1arv, afin que la demande puisse être lancée au serveur. Étant donné que d'autres clients ne connaissent pas cette règle, ils ne peuvent demander directement www.test.com/qr?p=xxxxxx. Cette demande revient à la page de l'invite.
Comment simplifier le code QR
Plusieurs fois, les chevaux sont invités à courir et à ne pas manger de l'herbe. Je veux que le code QR ait de nombreux paramètres, mais je ne veux pas que le code QR soit trop compliqué et il est difficile de scanner le code. Pour le moment, vous devez réfléchir à la façon de rendre le code QR simple sans affecter l'entreprise.
Exemple de code
Générez du code QR (supprimez les bords blancs et ajoutez le logo du milieu)
Besoin d'importer le package JAR: zxing de zxing's core-2.0.jar
Importer java.awt.basicStroke; import java.awt.color; import java.awt.graphics; importer java.awt.graphics2d; import java.awt.image; import java.awt.shape; import java.awt.geom.roundrectangle2d; import java.awt.image.bfferedrimage; java.io.bytearrayoutputStream; import java.io.fileoutputStream; import java.io.ioexception; import java.util.hashmap; import java.util.map; import javax.imageio.imageio; com.google.zxing.multiformatwriter; import com.google.zxing.common.bitmatrix; import com.google.zxing.qrcode.decoder.errorcorrectionLevel; public class qrcodeUtil {private static final int noir = colore.black.getrgb (); Final statique privé int blanc = color.white.getrgb (); private static final int default_qr_size = 183; chaîne finale statique privée default_qr_format = "png"; octet final final statique privé [] vide_bytes = nouveau octet [0]; Public Static octet [] CreateQrCode (String Content, int Size, String Extension) {return CreateQrCode (contenu, taille, extension, null); } / ** * Générez un code QR avec une image * @param Informations de contenu à inclure dans le code QR * @param size taille * @param Extension Format de fichier * @param insertimg L'image du logo du milieu * @return * / public static octet [] Createqrcode (String Content, int size, string extension, Image insertimg) {size <= 0) {throw negaLe taille + ") ne peut pas être <= 0"); } BytearrayoutputStream baos = null; essayez {map <encodeHintType, objet> hins = new hashmap <encodeHintType, objet> (); hint.put (encodeHintType.Character_set, "UTF-8"); hint.put (encodeHintType.Error_Correction, errorCorrectionLevel.m); // Utiliser des informations pour générer une matrice de points de taille spécifiée BitMatrix M = new MultiformatWriter (). Encode (contenu, BarcodeFormat.qr_code, taille, taille, indices); // supprimer le bord blanc m = updatebit (m, 0); int width = m.getWidth (); int hauteur = m.getheight (); // Définissez les informations dans BitMatrix dans le Bufferdimage pour former une image en noir et blanche BufferedImage Image = new BufferedImage (largeur, hauteur, bufferedImage.type_int_rgb); pour (int i = 0; i <largeur; i ++) {pour (int j = 0; j <hauteur; j ++) {image.setrgb (i, j, m.get (i, j)? noir: blanc); }} if (insertimg! = null) {// Insérez l'image du logo du milieu insertimage (image, insertimg, m.getWidth ()); } // agrandir l'image qui devient plus petite en raison de la suppression de l'image de bord blanche = zoomimage (image, taille, taille); baos = new bytearrayoutputStream (); Imageo.write (image, extension, baos); return baos.toByteArray (); } catch (exception e) {} enfin {if (baos! = null) try {baos.close (); } catch (ioException e) {// TODO Bloc de capture généré automatiquement e.printStackTrace (); }} return vide_bytes; } / ** * Code QR personnalisé Largeur de bord blanc * @param matrix * @param margin * @return * / private static bitMatrix updateBit (BitMatrix Matrix, int margin) {int tempm = margin * 2; int [] rec = matrix.getCllosingRectangle (); // Obtenez l'attribut du modèle de code QR int reswidth = rec [2] + tempm; int resheight = rec [3] + tempm; BitMatrix ResMatrix = new BitMatrix (Reswidth, Resheight); // générer un nouveau bitmatrix resMatrix.Clear () en fonction de la bordure personnalisée; pour (int i = margin; i <reswidth - margin; i ++) {// boucle pour dessiner le modèle de code QR dans le nouveau bitmatrix pour (int j = margin; j <resheight - margin; j ++) {if (matrix.get (i - margin + rec [0], j - margin + rec [1]) {Resmatrix.set (i, j); }} return resMatrix; } // Image Zoom inféromant et sortant public statique BufferedImage ZoomImage (BufferedImage OriginalMage, int largeur, int hauteur) {BufferedImage NewImage = new BufferedImage (Width, Height, OriginalImage.getType ()); Graphiques g = newImage.getGraphics (); G.DrawImage (originalMage, 0, 0, largeur, hauteur, null); g.dispose (); retourner NewImage; } private static void insertimage (BufferedImage Source, Image insertImg, int size) {try {int width = insertimg.getWidth (null); int hauteur = insertimg.getheight (null); largeur = largeur> taille / 6? Taille / 6: largeur; // Définissez le logo sur un sixième de la taille de la hauteur du code QR = hauteur> taille / 6? Taille / 6: hauteur; Graphics2d graph = source.creategraphics (); int x = (taille - largeur) / 2; int y = (taille - hauteur) / 2; graph.Drawimage (insertimg, x, y, largeur, hauteur, null); Forme de forme = nouveau RoundRectangle2d.float (x, y, largeur, largeur, 6, 6); Graph.SetStroke (New BasicStroke (3F)); graph.-draw (forme); graph.dispose (); } catch (exception e) {e.printStackTrace (); }} public static byte [] createqrcode (String Content) {return CreateQrCode (contenu, 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 Bloc de capture généré automatiquement e.printStackTrace (); }}}Générer des liens courts
Idées de base:
La théorie de l'algorithme de mappage de l'URL court:
1. Utilisez l'algorithme MD5 pour générer une chaîne de signature 32 bits, divisée en 4 segments, chaque segment avec 8 caractères.
2. Pour ces 4 segments, prenez 8 caractères dans chaque segment, traitez-le comme un peu et le fonctionnement de la chaîne hexadécimale et 0x3FFFFFFFF (30 bits 1), et ignorez le traitement de plus de 30 bits.
3. Divisez les 30 chiffres obtenus dans chaque segment en 6 segments, et chaque nombre à 5 chiffres est utilisé comme index de l'alphabet pour obtenir des caractères spécifiques et obtenir une chaîne 6 bits à son tour;
4. Une telle chaîne MD5 peut obtenir 4 chaînes 6 bits, et l'une d'entre elles peut être utilisée comme adresse URL courte de cette URL longue.
5. Il est préférable d'utiliser une base de données de valeurs clés pour la stocker. En cas de collision, remplacez-en un. Si les quatre entrent en collision, régénérez MD5 (car il y a des nombres aléatoires, différents MD5 seront générés)
Classe publique Droitlutil {/ ** * passer en valeur MD5 32 bits * @param md5 * @return * / public static String [] shortl (String md5) {// pour utiliser le caractère qui génère la chaîne url [] Chars = nouvelle chaîne [] {"A", "B", "C", "," E "," F " "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "," 6 "," 7 "," "8", "," a ",", "", "," 7 "," "8", "," a "," B ",", "7", "" 8 ",", "A", "B", "," 7 "," "8", "," A "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]; pour (int i = 0; i <4; i ++) {// Mettez les caractères chiffrés car 8 bits sont un ensemble d'hexadecimal et 0x3ffffffffffff et effectuer un bit et des calculs. Si plus de 30 bits sont ignorés String STEMPSUBSTRING = MD5.Substring (i * 8, i * 8 + 8); // Vous devez utiliser le type long pour convertir ici, car Inteper .ParseIntt () ne peut traiter que 31 bits, et le premier bit est le bit de signe. Si vous n'utilisez pas longtemps, il sera hors limites longues lhexlong = 0x3fffffff & long.parselong (STEMPSUBSTRING, 16); String outchars = ""; pour (int j = 0; j <6; j ++) {// Faire la valeur obtenue avec 0x000003d Effectuez du bit et de l'opération pour obtenir l'index de caractères du tableau de caractères Long Index = 0x0000003d & lhexlong; // Ajouter les caractères obtenus Outchars + = chars [(int) index]; // chaque boucle est bit-droite décalée de 5 bits lhexlong = lhexlong >> 5; } // Enregistrez la chaîne dans le tableau de sortie de l'index correspondant resurl [i] = outchars; } return resurl; } public static void main (String [] args) {String [] test = shortl ("fdf8d941f23680be79af83f921b107ac"); for (String String: test) {System.out.println (String); }}} Remarque: le code de base n'est pas original et emprunte le code des autres, merci!
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.