- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java二维码登录流程实现代码(包含短地址生成,含部分代码)由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
近年来,二维码的使用越来越风生水起,笔者最近手头也遇到了一个需要使用二维码扫码登录网站的活,所以研究了一下这一套机制,并用代码实现了整个流程,接下来就和大家聊聊二维码登录及的那些事儿.
二维码原理 。
二维码是微信搞起来的,当年微信扫码二维码登录网页微信的时候,感觉很神奇,然而,我们了解了它的原理,也就没那么神奇了。二维码实际上就是通过黑白的点阵包含了一个url请求信息。端上扫码,请求url,做对应的操作.
一般性扫码操作的原理 。
微信登录、支付宝扫码支付都是这个原理:
1. 请求二维码 。
桌面端向服务器发起请求一个二维码的.
2. 生成包含唯一id的二维码 。
桌面端会随机生成一个id,id唯一标识这个二维码,以便后续操作.
3. 端上扫码 。
移动端扫码二维码,解chu出二维码中的url请求.
4. 移动端发送请求到服务器 。
移动端向服务器发送url请求,请求中包含两个信息,唯一id标识扫的是哪个码,端上浏览器中特定的cookie或者header参数等会标识由哪个用户来进行扫码的.
5. 服务器端通知扫码成功 。
服务器端收到二维码中信息的url请求时,通知端上已经扫码成功,并添加必要的登录Cookie等信息。这里的通知方式一般有几种:websocket、轮训hold住请求直到超时、隔几秒轮训.
二维码中url的艺术 。
如何实现自有客户端和其他客户端扫码(如微信)表现的不同 。
比如,在业务中,你可能想要这样的操作,如果是你公司的二维码被其他app(如微信)所扫描,想要跳转一个提示页,提示页上可以有一个app的下载链接;而当被你自己的app所扫描时,直接进行对应的请求.
这种情况下,可以这样来做,所有二维码中的链接都进行一层加密,然后统一用另一个链接来处理.
如:www.test.com/qr?p=xxxxxx,p参数中包含服务器与客户端约定的加解密算法(可以是对称的也可以是非对称的),端上扫码到这种特定路径的时候,直接用解密算法解p参数,得到www.testqr.com/qrcode?key=s1arV,这样就可以向服务器发起请求了,而其他客户端因为不知道这个规则,只能直接去请求www.test.com/qr?p=xxxxxx,这个请求返回提示页.
如何让二维码更简单 。
很多时候,又要马儿跑,又要马儿不吃草。想要二维码中带有很多参数,但是又不想要二维码太复杂,难以被扫码出来。这时候,就需要考虑如何在不影响业务的情况下让二维码变的简单.
示例代码 。
生成二维码(去掉白边,增加中间的logo) 。
需要导入jar包:zxing的 core-2.0.jar 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
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.BufferedImage;
import
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.google.zxing.EncodeHintType;
import
com.google.zxing.MultiFormatWriter;
import
com.google.zxing.common.BitMatrix;
import
com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
public
class
QrCodeUtil {
private
static
final
int
BLACK = Color.black.getRGB();
private
static
final
int
WHITE = Color.WHITE.getRGB();
private
static
final
int
DEFAULT_QR_SIZE =
183
;
private
static
final
String DEFAULT_QR_FORMAT =
"png"
;
private
static
final
byte
[] EMPTY_BYTES =
new
byte
[
0
];
public
static
byte
[] createQrCode(String content,
int
size, String extension) {
return
createQrCode(content, size, extension,
null
);
}
/**
* 生成带图片的二维码
* @param content 二维码中要包含的信息
* @param size 大小
* @param extension 文件格式扩展
* @param insertImg 中间的logo图片
* @return
*/
public
static
byte
[] createQrCode(String content,
int
size, String extension, Image insertImg) {
if
(size <=
0
) {
throw
new
IllegalArgumentException(
"size ("
+ size +
") cannot be <= 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().encode(content, BarcodeFormat.QR_CODE, size, size, hints);
//去掉白边
m = updateBit(m,
0
);
int
width = m.getWidth();
int
height = m.getHeight();
//将BitMatrix中的信息设置到BufferdImage中,形成黑白图片
BufferedImage image =
new
BufferedImage(width, height, 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
) {
// 插入中间的logo图片
insertImage(image, insertImg, m.getWidth());
}
//将因为去白边而变小的图片再放大
image = zoomInImage(image, size, size);
baos =
new
ByteArrayOutputStream();
ImageIO.write(image, extension, baos);
return
baos.toByteArray();
}
catch
(Exception e) {
}
finally
{
if
(baos !=
null
)
try
{
baos.close();
}
catch
(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return
EMPTY_BYTES;
}
/**
* 自定义二维码白边宽度
* @param matrix
* @param margin
* @return
*/
private
static
BitMatrix updateBit(BitMatrix matrix,
int
margin) {
int
tempM = margin *
2
;
int
[] rec = matrix.getEnclosingRectangle();
// 获取二维码图案的属性
int
resWidth = rec[
2
] + tempM;
int
resHeight = rec[
3
] + tempM;
BitMatrix resMatrix =
new
BitMatrix(resWidth, resHeight);
// 按照自定义边框生成新的BitMatrix
resMatrix.clear();
for
(
int
i = margin; i < resWidth - margin; i++) {
// 循环,将二维码图案绘制到新的bitMatrix中
for
(
int
j = margin; j < resHeight - margin; j++) {
if
(matrix.get(i - margin + rec[
0
], j - margin + rec[
1
])) {
resMatrix.set(i, j);
}
}
}
return
resMatrix;
}
// 图片放大缩小
public
static
BufferedImage zoomInImage(BufferedImage originalImage,
int
width,
int
height) {
BufferedImage newImage =
new
BufferedImage(width, height, originalImage.getType());
Graphics g = newImage.getGraphics();
g.drawImage(originalImage,
0
,
0
, width, height,
null
);
g.dispose();
return
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
? size /
6
: width;
// logo设为二维码的六分之一大小
height = height > size /
6
? size /
6
: height;
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
(Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
|
生成短链接 。
基本思路:
短网址映射算法的理论:
1.将长网址加随机数用用md5算法生成32位签名串,分为4段,每段8个字符 。
2.对这4段循环处理,取每段的8个字符, 将他看成16进制字符串与0x3fffffff(30位1)的位与操作,超过30位的忽略处理 。
3.将每段得到的这30位又分成6段,每5位的数字作为字母表的索引取得特定字符,依次进行获得6位字符串; 。
4.这样一个md5字符串可以获得4个6位串,取里面的任意一个就可作为这个长url的短url地址.
5.最好是用一个key-value数据库存储,万一发生碰撞换一个,如果四个都发生碰撞,重新生成md5(因为有随机数,会生成不一样的md5) 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
public
class
ShortUrlUtil {
/**
* 传入32位md5值
* @param md5
* @return
*/
public
static
String[] shortUrl(String md5) {
// 要使用生成 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"
,
"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[] resUrl =
new
String[
4
];
for
(
int
i =
0
; i <
4
; i++) {
// 把加密字符按照 8 位一组 16 进制与 0x3FFFFFFF 进行位与运算,超过30位的忽略
String sTempSubString = md5.substring(i *
8
, i *
8
+
8
);
// 这里需要使用 long 型来转换,因为 Inteper .parseInt() 只能处理 31 位 , 首位为符号位 , 如果不用 long ,则会越界
long
lHexLong =
0x3FFFFFFF
& Long.parseLong(sTempSubString,
16
);
String outChars =
""
;
for
(
int
j =
0
; j <
6
; j++) {
// 把得到的值与 0x0000003D 进行位与运算,取得字符数组 chars 索引
long
index =
0x0000003D
& lHexLong;
// 把取得的字符相加
outChars += chars[(
int
) index];
// 每次循环按位右移 5 位
lHexLong = lHexLong >>
5
;
}
// 把字符串存入对应索引的输出数组
resUrl[i] = outChars;
}
return
resUrl;
}
public
static
void
main(String [] args){
String[] test = shortUrl(
"fdf8d941f23680be79af83f921b107ac"
);
for
(String string : test) {
System.out.println(string);
}
}
}
|
说明:核心代码非原创,借鉴了他人的代码,感谢! 。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:http://www.cnblogs.com/shenpengyan/p/6120257.html 。
最后此篇关于Java二维码登录流程实现代码(包含短地址生成,含部分代码)的文章就讲到这里了,如果你想了解更多关于Java二维码登录流程实现代码(包含短地址生成,含部分代码)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在尝试使用以下 keytool 命令为我的应用程序生成 keystore : keytool -genkey -alias tomcat -keystore tomcat.keystore -ke
编辑:在西里尔正确解决问题后,我注意到只需将生成轴的函数放在用于生成标签的函数下面就可以解决问题。 我几乎读完了 O'Reilly 书中关于 D3.js 的教程,并在倒数第二页上制作了散点图,但是当添
虽然使用 GraphiQL 效果很好,但我的老板要求我实现一个用户界面,用户可以在其中通过 UI 元素(例如复选框、映射关系)检查呈现给他们的元素并获取数据,这样做将为该人生成 graphql 输入,
我尝试在 Netbean 6.8 中使用 ws-import 生成 Java 类。我想重新生成 jax-ws,因为在 ebay.api.paypalapi 包中发现了一个错误(我认为该错误是由于 Pa
我有一个 perl 脚本,它获取系统日期并将该日期写入文件名。 系统日期被分配给 TRH1 变量,然后它被设置为一个文件名。 $TRH1 =`date + %Y%m%d%H%M`; print "TR
我是 Haskell 的新手,需要帮助。我正在尝试构建一种必须具有某种唯一性的新数据类型,因此我决定使用 UUID 作为唯一标识符: data MyType = MyType { uuid ::
我制作了一个脚本,它可以根据 Mysql 数据库中的一些表生成 XML。 该脚本在 PHP 中运行。 public function getRawMaterials($apiKey, $format
所以这是我的项目中的一个问题。 In this task, we will use OpenSSL to generate digital signatures. Please prepare a f
我在 SAS LIFEREG 中有一个加速故障时间模型,我想绘制它。因为 SAS 在绘图方面非常糟糕,我想实际重新生成 R 中曲线的数据并将它们绘制在那里。 SAS 提出了一个尺度(在指数分布固定为
我正在为 Django 后端制作一个样板,并且我需要能够使它到达下一个下载它的人显然无法访问我的 secret key 的地方,或者拥有不同的 key 。我一直在研究一些选项,并在这个过程中进行了实验
我正在创建一个生成采购订单的应用程序。我可以根据用户输入的详细信息创建文本文件。我想生成一个看起来比普通文本文件好得多的 Excel。有没有可以在我的应用程序中使用的开源库? 最佳答案 目前还没有任何
我正在尝试使用 ScalaCheck 为 BST 创建一个 Gen,但是当我调用 .sample 方法时,它给了我 java.lang.NullPointerException。我哪里错了? seal
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我尝试编写一些代码,例如(在verilog中): parameter N = 128; if (encoder_in[0] == 1) begin 23 binary_out = 1;
我正忙于在 Grails 项目中进行从 MySQL 到 Postgres 的相当复杂的数据迁移。 我正在使用 GORM 在 PostGres 中生成模式,然后执行 MySQL -> mysqldump
如何使用纯 XSLT 生成 UUID?基本上是寻找一种使用 XSLT 创建独特序列的方法。该序列可以是任意长度。 我正在使用 XSLT 2.0。 最佳答案 这是一个good example 。基本上,
我尝试安装.app文件,但是当我安装并单击“同步”(在iTunes中)时,我开始在设备上开始安装,然后停止,这是一个问题,我不知道在哪里,但我看到了我无法解决的奇怪的事情: 最佳答案 似乎您没有在Xc
自从我生成 JavaDocs 以来已经有一段时间了,我确信这些选项在过去 10 年左右的时间里已经得到了改进。 我能否得到一些有关生成器的建议,该生成器将输出类似于 .Net 文档结构的 JavaDo
我想学习如何生成 PDF,我不想使用任何第三方工具,我想自己用代码创建它。到目前为止,我所看到的唯一示例是我通过在第 3 方 dll 上打开反射器查看的代码,以查看发生了什么。不幸的是,到目前为止我看
我正在从 Epplus 库生成 excel 条形图。 这是我成功生成的。 我的 table 是这样的 Mumbai Delhi Financial D
我是一名优秀的程序员,十分优秀!