近年、QRコードの使用はますます繁栄しています。最近、QRコードをスキャンしてWebサイトにログインする必要があるジョブに遭遇しました。そこで、私はこのメカニズムを研究し、コードを使用してプロセス全体を実装しました。次に、QRコードログインなどについてお話しします。
QRコードの原則
QRコードはWeChatによって作成されました。 WeChatでQRコードをスキャンすると、WeChatのWebページにログインすると非常に魔法のように感じました。しかし、その原則を理解した後、それはそれほど魔法ではありません。 QRコードには、実際には、白黒ドットマトリックスを介したURL要求情報が含まれています。端末のコードをスキャンし、URLを要求し、対応する操作を実行します。
一般的なコードスキャン操作の原則
これは、WeChatログインとAlipayスキャンのコード支払いの原則です。
1. QRコードをリクエストします
デスクトップは、サーバーへのQRコード要求を開始します。
2。一意のIDでQRコードを生成します
デスクトップはIDをランダムに生成し、IDは後続の操作のためにこのQRコードを一意に識別します。
3.ボード上のコードをスキャンします
モバイル端末のQRコードをスキャンして、QRコードのURL要求を解決します。
4.モバイル端末はサーバーにリクエストを送信します
モバイル端末は、2つの情報を含むURL要求をサーバーに送信します。一意のIDは、どのコードがスキャンされているかを識別し、端末のブラウザ内の特定のCookieまたはヘッダーパラメーターは、どのユーザーがコードをスキャンするかを識別します。
5。コードを正常にスキャンするためのサーバー側の通知
サーバーがQRコードの情報に対するURL要求を受信すると、通知側はコードを正常にスキャンし、必要なログインCookieおよびその他の情報を追加しました。ここには一般にいくつかの通知方法があります:WebSocket、トレーニングはタイムアウトまでリクエストを保持し、トレーニングには数秒かかります。
QRコードのURLのアート
自分のクライアントと他のクライアントの間のスキャンコード(WeChatなど)の違いを実現する方法
たとえば、ビジネスでは、これを行うことができます。会社のQRコードが他のアプリ(WeChatなど)によってスキャンされ、プロンプトページにジャンプしたい場合は、プロンプトページにアプリのダウンロードリンクがあります。また、独自のアプリによってスキャンされたら、対応するリクエストを直接作成します。
この場合、これを実行できます。QRコードのすべてのリンクは、1つのレイヤーで暗号化され、別のリンクで処理されます。
たとえば、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
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.RoundRectangre2d; Import Java.Awt.Awt.image.Awt.image java.io.bytearrayoutputStream; Import java.io.fileOutputStream; Import java.io.ioexception; Import java.util.hashmap; Import javax.imageio.imageio; Import com.google.zxd. com.google.zxing.multiformatwriter; import com.google.zxing.common.bitmatrix; import com.google.zxing.qrcode.decoder.errorcorrectionlevel;パブリッククラスqrcodeutil {private static final int black = color.getrgb(); private static final int white = color.white.getrgb();プライベート静的最終int default_qr_size = 183;プライベート静的最終文字列default_qr_format = "png"; private static final final byte [] empty_bytes = new byte [0]; public static byte [] createqrcode(string content、int size、string endix){return createqrcode(content、size、extension、null); } / ***画像* @Paramコンテンツ情報を使用してQRコードを生成するQRコード* @Param拡張機能サイズ* @param拡張機能フォーマット拡張機能* @param Insertimg insertimg the Middleロゴ画像* @return* / public static byte [] createqrcode(int int、int size、string extension、image intersine ")<= 0になることはできません"); } bytearrayoutputStream baos = null; try {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()。エンコード(content、barcodeformat.qr_code、サイズ、サイズ、ヒント)のドットマトリックスを生成します。 //ホワイトエッジm = updatebit(m、0); int width = m.getWidth(); int height = m.getheight(); // BitMatrixの情報をBufferDimageに設定して、白黒画像BufferedImage = 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 = new bytearrayoutputStream(); Imageio.write(画像、拡張子、baos); return baos.tobytearray(); } catch(例外e){}最後に{if(baos!= null)try {baos.close(); } catch(ioException e){// todo auto-fenated catch block e.printstacktrace(); }} empty_bytesを返します。 } / ** *カスタムQRコードホワイトエッジ幅 * @Param Matrix * @Param Margin * @return * / 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); // Custom Borderに従って新しいBitmatrix resmatrix.clear()を生成します。 for(int i = margin; i <reswidth -margin; i ++){// loop for(int j = margin; j <resheight -margin; j ++){if(matrix.get(i -margin+rec [0]、j -margin+rec [1])) }} Resmatrixを返します。 } //画像ズームインおよびパブリックスタティック緩衝液zoominimage(bufferedimage originalimage、int width、int height){bufferedimage newimage = new bufferedimage(width、height、originalimage.getType());グラフィックg = newimage.getGraphics(); g.drawimage(originalimage、0、0、width、height、null); g.dispose(); NewImageを返します。 } private static void insertimage(bufferedimage source、image insertimg、int size){try {int width = insertimg.getWidth(null); int height = insertimg.getheight(null); width = width> size / 6?サイズ / 6:幅; //ロゴをQRコードの高さのサイズの6分の1に設定します=高さ>サイズ / 6?サイズ / 6:高さ; 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、width、width、6、6); graph.setStroke(new BasicStroke(3F)); graph.draw(shape); 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(例外e){// todo auto-enerated catch block e.printstacktrace(); }}}短いリンクを生成します
基本的なアイデア:
短いURLマッピングアルゴリズムの理論:
1. MD5アルゴリズムを使用して、32ビットの署名文字列を生成し、4つのセグメントに分割され、各セグメントは8文字のセグメントです。
2。これらの4つのセグメントでは、各セグメントで8文字を取り、それを少し扱い、16進文字列と0x3ffffffffff(30ビット1)の動作として扱い、30ビット以上の処理を無視します。
3.各セグメントで得られた30桁を6つのセグメントに分割し、それぞれ5桁の数字をアルファベットのインデックスとして使用して特定の文字を取得し、6ビット文字列を順番に取得します。
4.このようなMD5文字列は4つの6ビット文字列を取得でき、それらのいずれかはこの長いURLの短いURLアドレスとして使用できます。
5.キー価値データベースを使用して保存するのが最善です。衝突の場合は、1つを交換します。 4つすべてが衝突する場合、MD5を再生します(乱数があるため、異なるMD5が生成されます)
Public Class Shorturlutil { / ** * 32ビットMD5値でパス * @Param MD5 * @return * / public Static String [] Shorturl(String Md5){// "" "、" l "、" m "、" n "、" o "、" p "、" "、" r "、" s "、" t "、u"、 "v"、 "v"、 "w" x "、y"、 "z"、 "0" "1"、 "2"、 "3"、 "4"、 "" b "" "b"、 "" "8"、 "" "、" d "、" e "、" f "、" g "、" h "、" i "、" j "、" "" 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 ++){//暗号化された文字を8ビットは16進数と0x3ffffffffffffffのセットとして配置し、ビットと計算を実行します。 30ビット以上が無視されている場合、文字列stempsubstring = md5.substring(i * 8、i * 8 + 8); // inteper .parseint()は31ビットのみを処理できるため、ここで長いタイプを使用してここに変換する必要があり、最初のビットはサインビットです。長く使用しない場合、それは長い範囲外になります。文字列outchars = ""; for(int j = 0; j <6; j ++){// 0x000003Dで取得した値をビットと操作を実行して、文字配列chars long index = 0x0000003d&lhexlongを取得します。 //取得した文字を追加しますoutchars += chars [(int)index]; //各ループはビット右シフトされていますlhexlong = lhexlong >> 5; } //文字列を対応するインデックスの出力配列に保存します[i] = outchars; } RESURLを返します。 } public static void main(string [] args){string [] test = shorturl( "FDF8D941F23680BE79AF83F921B107AC"); for(string string:test){system.out.println(string); }}}注:コアコードはオリジナルではなく、他の人のコードから借用しています。ありがとうございます!
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。