二维码生成以及扫一扫解析二维码原理

二维码生成以及扫一扫解析二维码原理


1、生成URL,确定要通过二维码传达的信息,也就是通过扫一扫可以获得地址和数据信息


1、// 得到随机数,用随机数得到签名,签名验证身份
String ranString = RandomStringUtils.randomAlphanumeric(10);


2、其他参数信息,在二维码中存储的信息非常有限,所有在微信,支付宝的二维码一般不带参数,而是只包含地址信息,在其地址中就包含相应的信息,微信或者支付宝
//在这一般上送标识字段不上送数据信息,状态字段用于判断什么状态下执行什么操作
String orderNo = "123456";
Map<String, String> maps = new HashMap<String, String>();
maps.put("orderNo", orderNo);
maps.put("xx", xx);


3、// 根据规则生成URL,这个URL就是存放到二维码中的数据
String url = generateUrl(ranString, maps);
System.out.println("生成后的URL为: " + url);


4、生成URL方法

// 扫描二维码需要访问的URL,如果是想访问自己的App,则把相应的APP地址放到二维码中
private static final String BASE_URL = "https://st1.tyest.com/app-server";
/**
* 生成二维码URL地址
* @param paramMaps
*            上送字段map
* @param RanSign
*            随机数
* @return
* @throws Exception
*/
public static String generateUrl(String RanSign, Map<String, String> paramMaps) {
String url = null;
String data = "";
try {
// 拼接业务信息字符串,需要上送的字段信息
for (Iterator<Entry<String, String>> it = paramMaps.entrySet()
.iterator(); it.hasNext();) {
Entry<String, String> entry = it.next();
String inputPartkey = entry.getKey();
String inputPart = entry.getValue();
data += inputPartkey + "=" + inputPart + "&";
}
// 对数据信息加密,可以加密,但是二维码存放不下aes加密后的数据,太大了
/*AES aes = new AES();
String HexString = aes.encrypt(data, AES_KEY);*/
//拼接的字符串多了&,类似data=XXX&sign=XXX
data=(String) data.subSequence(0, data.length()-1);
System.out.println("业务信息字符串: " + data);
// 对业务信息进行签名,得到签名信息,包含上送字段,这就是通过扫一扫后得到地址后面一串很长的字符串
String sign = SHA1.genSign(RanSign);
System.out.println("签名: " + sign);
// 后面的则是需要访问的具体的接口,以及需要上送的参数,上送字段可以选择是否加密
url = BASE_URL + "/test/testInterface?sign=" + sign + "&data=" + data;
} catch (Exception e) {
e.printStackTrace();
}
return url;
}


5、绘制二维码


// 根据URL生成二维码图片,把上面的URL以及参数信息写到二维码中,添加logo图片的路径


String logoPath = "D:\\testbail.png";
BufferedImage image = QrCodeImgUtil.qrCodeEncode(url, logoPath);

// 得到outputStream把数据信息写出来
OutputStream out = new FileOutputStream(new File("D:\\testbail.png"));
//把图片绘制到给出的画板上
ImageIO.write(image, "png", out);
System.out.println("图片生成完成");
System.out.println("ranString=" + ranString);


6、绘制方法,网上其实有很多的类似方法,不过还是说下吧
public static BufferedImage qrCodeEncode(String encodeddata,String logoPath)
throws IOException {
Qrcode qrcode = new Qrcode();
// 纠错级别(L 7%、M 15%、Q 25%、H 30%)和版本有关
qrcode.setQrcodeErrorCorrect('M'); 
qrcode.setQrcodeEncodeMode('B');
qrcode.setQrcodeVersion(7); // 设置Qrcode包的版本

byte[] d = encodeddata.getBytes("utf-8"); // 字符集
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 创建图层
Graphics2D g = bi.createGraphics();

g.setBackground(Color.WHITE); // 设置背景颜色(白色)
g.clearRect(0, 0, width, height); // 矩形 X、Y、width、height
g.setColor(Color.BLACK); // 设置图像颜色(黑色)


if (d.length > 0 && d.length < 123) {
boolean[][] b = qrcode.calQrcode(d);
for (int i = 0; i < b.length; i++) {
for (int j = 0; j < b.length; j++) {
if (b[j][i]) {
g.fillRect(j * 3 + 2, i * 3 + 2, 3, 3);
}
}
}
}


/* 添加logo图片 */  
if(logoPath!=null){  
int width_4 = width / 4;  
int width_8 = width_4 / 2;  
int height_4 = height / 4;  
int height_8 = height_4 / 2;  
Image img = ImageIO.read(new File(logoPath));  
g.drawImage(img, width_4 + width_8, height_4 + height_8,width_4,height_4, null);  
g.dispose();    
bi.flush();  



g.dispose(); // 释放此图形的上下文以及它使用的所有系统资源。调用 dispose 之后,就不能再使用 Graphics 对象
bi.flush(); // 刷新此 Image 对象正在使用的所有可重构的资源
return bi;
}

6、打开D:\\testbail.png生产的二维码图片,通过扫一扫可以得到如下的类似信息

https://st1.tyest.com/app-server/test/testInterface?sign=a094bb8f56bd2beac35949a76e2ca35dd6e69c87&orderNo=123456

这个就是我们常见的URL了,通过浏览器就可以访问了。



2、 二维码的解析:


1、代码解析二维码图片

//解析的二维码路径
String imgPath = "D:\\testbail.png";
File imageFile = new File(imgPath);
// 测试解析二维码图片内容
String decoderContent = QrCodeImgUtil.qrCodeDecode(imageFile);
System.out.println(decoderContent);
System.out.println("=========解码成功===========");

首先我们要知道,代码解析会解析图片上的所有信息,当然包括图片信息,
然而图片logo是外加入的,所以通过代码解析不了带有logo的二维码,这一点
我还没想到怎么做,有知道的

相关实现方法:
/**
* 解析二维码,返回解析内容

* @param imageFile
* @return
*/
public static String qrCodeDecode(File imageFile) {
String decodedData = null;
QRCodeDecoder decoder = new QRCodeDecoder();
BufferedImage image = null;
try {
image = ImageIO.read(imageFile);
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}


try {
decodedData = new String(decoder.decode(new J2SEImage(image)),"utf-8");
} catch (DecodingFailedException dfe) {
System.out.println("Error: " + dfe.getMessage());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return decodedData;
}

得到结果:
https://st1.tyest.com/app-server/test/testInterface?sign=d4b8ae6e19daf14fb8dbaac9ce6ce9bc6f8679f5&orderNo=123456
=========解码成功===========

2、通过扫一扫工具解析(最简单的一种解析方式)


3、扫描二维码背后的故事:

通过上面的方式我们生产了我们自己的二维码,通过扫一扫就可以访问我们自己的系统实现相应的功能,
在这里我们模拟实现一下


String sign = "82385294b5eee3adb2fcedcf0868a219e0e69e1f";
String data = "orderNo=123456";
String ranString ="GJ5U6PfwbyvA8WZxEJt8s7rKqYQzEl6v";
// 假设该方法就是我们定义的接口,而这两个参数正式通过扫一扫获得数据信息。模拟调接口
testInterface(ranString, sign, data);


private static void testInterface(String ranString, String sign, String data) {
// 首先我们验证签名信息,正确则继续,否则验证不通过,二维码有误,在这里我们就知道了,用支付宝或者微信扫描彼此的二维码,就会提示无效的二维码
// 就是因为在验签的时候失败了,就无法继续
if (SHA1.verifySign(ranString, sign)) {
// 验签成功
// 对数据信息解密,如果数据加密的话
AES aes = new AES();
try {
String deString = aes.decrypt(data, AES_KEY);
System.out.println(deString);


// 做相应的业务处理逻辑

} catch (CryptException e) {
e.printStackTrace();
}


} else {
//扫二维码验签失败,说明不是可处理的二维码
System.out.println("二维码有误!");
}


}

扫描二维码就是访问接口,和我们平时写的接口一样的道理,多看看就会明白。
在我的资源里上传了二维码的代码,有需要的支持下,有不当之处,望各位猿友之处,万分感谢。


通过此实例,相信对二维码有了进一步的认识。

每天努力一点,每天都在进步。


  • 5
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
在Android操作系统中实现二维码生成与扫码功能是一个常见的需求,而为了方便实现该功能,可以选择使用二维码插件进行开发。Android平台上比较常用的二维码插件包括Zxing和QRCode等。 首先,在使用插件前需要在项目Gradle中添加插件依赖,就以Zxing为例,在项目build.gradle中添加依赖: ``` dependencies { implementation 'com.google.zxing:core:3.3.3' } ``` 生成二维码可以通过调用Zxing库中的MultiFormatWriter类来实现,示例代码: ``` MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); BitMatrix bitMatrix = multiFormatWriter.encode(textToEncode, BarcodeFormat.QR_CODE, qrCodeWidth, qrCodeHeight); BarcodeEncoder barcodeEncoder = new BarcodeEncoder(); Bitmap bitmap = barcodeEncoder.createBitmap(bitMatrix); ``` 其中,textToEncode表示要生成二维码的文本信息,qrCodeWidth和qrCodeHeight表示二维码的宽度和高度,一般情况下可以设置为200x200。 扫码功能需要调用Zxing库中的IntentIntegrator类,在代码中使用: ``` private void startScan() { IntentIntegrator integrator = new IntentIntegrator(this); integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES); integrator.setPrompt("Scan a QRcode"); integrator.setCameraId(0); integrator.setBeepEnabled(false); integrator.initiateScan(); } ``` 其中,setDesiredBarcodeFormats表示需要识别的码的类型,setPrompt表示扫码时的提示信息,setCameraId表示使用的相机,setBeepEnabled表示是否有声音提示。 当扫描完成后,需要在onActivityResult()方法中处理扫描结果,示例代码: ``` @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); if(result != null) { if(result.getContents() == null) { Log.d(TAG, "Cancelled"); } else { Log.d(TAG, "Scanned: " + result.getContents()); } } else { super.onActivityResult(requestCode, resultCode, data); } } ``` 在上述代码中,通过解析扫描结果的IntentResult类来获取识别出的二维码信息,如果result.getContents()为null则表示扫码取消,否则就可以得到扫描结果了。 总之,对于Android平台上的二维码生成与扫码功能实现,通过使用Zxing或QRCode等插件可以方便快捷地实现该需求,即通过调用插件提供的API来生成或识别二维码即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

powerfuler

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值