近期因为一些原因,从内网传输数据到外网的行为受到限制,便研究了些非正常手段进行数据传输
使用二维码 原理是在内网系统的屏幕上生成二维码,每秒刷新一次;在外网用拍照或者截屏的方式读取二维码图片,解码为数据。
单个QR码国际标准二维码,二进制模式最多可存储2953字节,2KB多一点,所以使用二维码进行数据传输其速率应该在几KB/S。
生成二维码 需要使用 PIL(pillow) 图像库, qrcode 二维码生成库,以及 tkinter UI界面库。 tkinter 默认随Python一起安装。
from PIL import Image, ImageTk import qrcode import base64 import tkinter def generateTkImages(data): tkImgs = [] for i in range(4): # 单次生成4张二维码图片,这里需要自己根据屏幕适配 content = b'需要传输的数据' #理论上不需要base64编码,但是实际测试使用pyzbar解码字节流二维码时会乱码,所以使用base64将字节流转为字符串 bs = base64.b64encode(content) #创建二维码容器,指定单个区块尺寸和边框尺寸 qr = qrcode.QRCode(box_size = 2,border = 2) #添加数据 qr.add_data(bs) #生成二维码图片 img = qr.make_image() #转换成tkinter支持的图像 tkImg = ImageTk.PhotoImage(image = img) tkImgs.append(tkImg) # 使用数组存储,避免因为tkinter的bug只显示最后一张 return tkImgs class QrApp(tkinter.Frame): def __init__(self,master = None): super().__init__(master) self.master = master self.pack() self.labels = [] for i in range(4): lb = tkinter.Label(self) lb.grid(row = int(i /2) , column = i % 2 ) # 2行 2 列 self.labels.append(lb) def test(self): tkImgs = generateTkImages(需要传输的数据) for i in range(4): self.labels[i].configure(image=tkImgs[i]) self.master.update() #更新界面 self.master.after(1000) # 保持1000毫秒 root = tkinter.Tk() root.geometry('1030x550+0+0') app = QrApp(root) root.after(500,app.test) root.mainloop() 二维码解码 本文使用 pyzbar 解码,图片来自截屏
...