최근 몇 년 동안 QR 코드의 사용은 점점 더 번영 해졌습니다. 최근에 QR 코드를 스캔하여 웹 사이트에 로그인 해야하는 작업이 발생했습니다. 그래서이 메커니즘을 연구하고 코드로 전체 프로세스를 구현했습니다. 다음으로 QR 코드 로그인 및 기타 사항에 대해 이야기하겠습니다.
QR 코드의 원리
QR 코드는 WeChat에 의해 작성되었습니다. WeChat에서 QR 코드를 스캔 할 때 WeChat 웹 페이지에 로그인했을 때 매우 마법 같은 느낌이 들었습니다. 그러나 원칙을 이해 한 후에는 마법이 아닙니다. QR 코드에는 실제로 흑백 도트 매트릭스를 통한 URL 요청 정보가 포함되어 있습니다. 터미널에서 코드를 스캔하고 URL을 요청한 다음 해당 작업을 수행하십시오.
일반 코드 스캔 작업의 원리
이것이 WeChat 로그인 및 Alipay 스캔 코드 결제의 원칙입니다.
1. QR 코드를 요청하십시오
데스크탑은 서버에 QR 코드 요청을 시작합니다.
2. 고유 한 ID로 QR 코드를 생성합니다
데스크탑은 ID를 무작위로 생성하며 ID는 후속 작업을 위해이 QR 코드를 고유하게 식별합니다.
3. 보드에서 코드를 스캔하십시오
모바일 터미널의 QR 코드를 스캔하여 QR 코드에서 URL 요청을 해결하십시오.
4. 모바일 터미널은 서버에 요청을 보냅니다.
모바일 터미널은 서버에 URL 요청을 보냅니다. 여기에는 두 가지 정보가 포함되어 있습니다. 고유 ID는 스캔되는 코드를 식별하고 터미널의 브라우저의 특정 쿠키 또는 헤더 매개 변수는 코드를 스캔 한 사용자를 식별합니다.
5. 코드를 성공적으로 스캔하는 서버 측 알림
서버가 QR 코드의 정보에 대한 URL 요청을 수신하면 알림 측면이 코드를 성공적으로 스캔하고 필요한 로그인 쿠키 및 기타 정보를 추가했습니다. 여기에는 일반적으로 몇 가지 알림 방법이 있습니다 : WebSocket, Timeout까지 교육 홀드 요청 및 교육은 몇 초가 걸립니다.
QR 코드의 URL 아트
자신의 클라이언트와 다른 클라이언트 간의 스캔 코드 (예 : WeChat)의 차이점을 실현하는 방법
예를 들어, 비즈니스에서는이 작업을 수행 할 수 있습니다. 회사의 QR 코드 (예 : WeChat)에서 회사의 QR 코드를 스캔하고 프롬프트 페이지로 이동하려면 프롬프트 페이지에 앱 다운로드 링크가있을 수 있습니다. 자신의 앱으로 스캔되면 해당 요청을 직접 작성하십시오.
이 경우이를 수행 할 수 있으며 QR 코드의 모든 링크는 한 계층으로 암호화 된 다음 다른 링크로 처리됩니다.
예를 들어 www.test.com/qr?p=xxxxxx, p 매개 변수에는 서버와 클라이언트가 합의한 암호화 및 암호 해독 알고리즘이 포함되어 있습니다 (대칭 또는 비대칭적일 수 있음). 터미널의 코드를이 특정 경로로 스캔 할 때 P 매개 변수는 직접 사용하여 P 매개 변수를 해결하고 www.testqr.com/qrcode?key=s1arv를 가져와 요청을 서버로 시작할 수 있습니다. 다른 클라이언트는이 규칙을 알지 못하기 때문에 www.test.com/qr?p=xxxxxx 만 직접 요청할 수 있습니다. 이 요청은 프롬프트 페이지로 돌아갑니다.
QR 코드를 더 간단하게 만드는 방법
여러 번, 말은 잔디를 먹지 말라고 요청받습니다. QR 코드에 많은 매개 변수가 있기를 원하지만 QR 코드가 너무 복잡해지기를 원하지 않으며 코드를 스캔하기가 어렵습니다. 현재 비즈니스에 영향을 미치지 않고 QR 코드를 간단하게 만드는 방법을 고려해야합니다.
샘플 코드
QR 코드 생성 (흰색 가장자리 제거 및 중간 로고 추가)
JAR 패키지를 가져와야합니다 : Zxing의 Core-2.0.jar
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.bufered 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.zx.zx.zx com.google.zxing.multiformatwriter; import com.google.zxing.common.bitmatrix; import com.google.zxing.qrcode.decoder.errorcorrectionlevel; public static final int black = color.black.getrgb (); 개인 정적 최종 int white = color.white.getrgb (); 비공개 정적 최종 int default_qr_size = 183; 개인 정적 최종 문자열 default_qr_format = "png"; 개인 정적 최종 최종 바이트 [] empty_bytes = 새로운 바이트 [0]; public static bd } / *** QR 코드* @param size size* @param 확장 파일 형식 확장자* @param insertimg 중간 로고 이미지* @return* / public static byte [] createQrcode (문자열 내용, 문자열 확장, 이미지 insertimg) {if (size <= 0) {newlerecence ( " + size +")는 <= 0 "); } BYTEARRAYOUTPUTSTREAM BAOS = NULL; {map <encodehinttype, object> hints = new Hashmap <encodehinttype, object> (); hints.put (encodehinttype.character_set, "utf-8"); hints.put (encodehinttype.error_correction, errorcorrectionlevel.m); // 지정된 크기의 점 매트릭스를 생성하기 위해 정보를 사용하여 bitmatrix m = new multiformatwriter (). // 흰색 에지 제거 m = updatebit (m, 0); int width = m.getWidth (); int height = m.getheight (); // Bitmatrix의 정보를 BufferDimage로 설정하여 흑백 이미지 BufferedImage Image = New BufferedImage (너비, 높이, 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, j)? black : white); }} if (insertImg! = null) {// 중간 로고 이미지 insertImage (image, insertImg, m.getWidth ()); } // 흰색 가장자리 이미지를 제거하여 더 작은 이미지를 확대합니다. Zoominimage (이미지, 크기, 크기); Baos = 새로운 BytearRayoutputStream (); imageio.write (이미지, 확장, baos); return baos.tobytearray (); } catch (예외 e) {} 마지막으로 {if (baos! = null) try {baos.close (); } catch (ioexception e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); }} return empty_bytes; } / ** * 사용자 정의 QR 코드 흰색 가장자리 너비 * @param matrix * @param margin * / private static bitmatrix updatebit (bitmatrix matrix, int margin) {int tempm = margin * 2; int [] rec = matrix.getEnclosingRectangle (); // QR 코드 패턴의 속성을 가져옵니다. int reswidth = rec [2] + tempm; int resheight = rec [3] + tempm; Bitmatrix resmatrix = New Bitmatrix (Reswidth, Resheight); // 사용자 정의 테두리에 따라 새 비트 매트릭스 resmatrix.clear ()를 생성합니다. for (int i = margin; i <reswidth -margin; i ++) {// 루프는 QR 코드 패턴을 새로운 비트 스마트 릭스 (int j = margin; j <resheight -margin; j ++)에 그리기위한 루프입니다 (if (matrix.get (i- margin+rec [0], j- margin [1])); }} return resmatrix; } // 이미지 확대 및 아웃 공개 정적 버퍼링이지 ZoominImage (bufferedImage originalImage, int width, int height) {bufferedImage newImage = new bufferedImage (너비, 높이, ordageImage.getType ()); 그래픽 g = newImage.getGraphics (); G.DrawImage (OriginalImage, 0, 0, 너비, 높이, 널); g.dispose (); Newimage를 반환하십시오. } private static void insertImage (bufferedImage 소스, 이미지 insertImg, int size) {try {int width = insertImg.getWidth (null); int height = insertimg.getheight (null); 너비 = 너비> 크기 / 6? 크기 / 6 : 너비; // 로고를 QR 코드 크기의 1/6으로 설정하십시오. 높이 = 높이> 크기 / 6? 크기 / 6 : 높이; Graphics2d Graph = source.creategraphics (); int x = (크기 - 너비) / 2; int y = (크기 - 높이) / 2; Graph.DrawImage (insertimg, x, y, 너비, 높이, 널); 모양 구성 = New RoundRectangle2d.float (x, y, 너비, 너비, 6, 6); Graph.SetStroke (New BasicStroke (3F)); Graph.Draw (모양); Graph.Dispose (); } catch (예외 e) {e.printstacktrace (); }} public static byte [] createqrcode (문자열 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 (예외 e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); }}}짧은 링크를 생성합니다
기본 아이디어 :
짧은 URL 매핑 알고리즘 이론 :
1. MD5 알고리즘을 사용하여 32 비트 서명 문자열을 생성하고 각 세그먼트로 나뉘어 진 각 세그먼트로 8 자입니다.
2.이 4 개의 세그먼트의 경우 각 세그먼트에서 8자를 가져 가서 육각형 문자열과 0x3ffffffff (30 비트 1)의 비트 및 작동으로 취급하고 30 비트 이상의 처리를 무시하십시오.
3. 각 세그먼트에서 얻은 30 자리를 6 개의 세그먼트로 나누고, 각 5 자리 숫자는 특정 문자를 얻기 위해 알파벳의 색인으로 사용되며, 6 비트 문자열을 차례로 얻습니다.
4. 이러한 MD5 문자열은 4 개의 6 비트 문자열을 얻을 수 있으며,이 중 하나는이 긴 URL의 짧은 URL 주소로 사용할 수 있습니다.
5. 키 값 데이터베이스를 사용하여 저장하는 것이 가장 좋습니다. 충돌의 경우 하나를 교체하십시오. 4 개 모두 충돌하면 MD5를 재생합니다 (임의의 숫자가 있으므로 다른 MD5가 생성됩니다)
public class shorturlutil { / ** * 32 비트 md5 value * @param md5 * @return * / public static string [] shorturl (string md5) {// URL 문자열을 생성하는 문자를 사용하는 문자열 [] {] { "a", "b", "c"d ","e ","g ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", "," "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", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "z"}; 문자열 [] resurl = 새 문자열 [4]; for (int i = 0; i <4; i ++) {// 암호화 된 문자를 8 비트로 16 진수 세트와 0x3ffffffffffff로 넣고 비트 및 계산을 수행합니다. 30 개 이상의 비트가 무시되면 문자열 stempsubstring = md5.substring (i * 8, i * 8 + 8); // inteper .parseint ()가 31 비트 만 처리 할 수 있고 첫 번째 비트는 부호 비트이므로 긴 유형을 사용해야합니다. 오래 사용하지 않으면 긴 lhexlong = 0x3fffffff & long.parselong (stempsubstring, 16); String OutChars = ""; for (int j = 0; j <6; j ++) {// 획득 된 값을 0x000003D로 수행하여 비트 및 작업을 수행하여 문자 배열 chars index long index = 0x0000003d & lhexlong; // 획득 된 문자 추가 outchars += chars [(int) index]; // 각 루프는 비트 오른쪽으로 5 비트로 이동합니다. lHexLong = lHexLong >> 5; } // 해당 인덱스 rebserl의 출력 배열에 문자열을 저장 [i] = OutChars; } return rebserl; } public static void main (String [] args) {String [] test = shorturl ( "fdf8d941f23680be79af83f921b107ac"); for (문자열 문자열 : test) {system.out.println (문자열); }}} 참고 : 핵심 코드는 독창적이지 않으며 다른 사람들의 코드에서 차용합니다. 감사합니다!
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.