跳转至

二维码生成流程

本文档详细描述了 qrcode_transfer 项目中二维码生成的完整流程,包括从输入文件到最终显示二维码的每个步骤及关键实现细节。

流程概览

二维码生成流程通过多个模块协作完成,包含以下核心步骤:

flowchart TD
    A[开始] --> B[初始化任务ID]
    B --> C[压缩文件/目录]
    C --> D[计算压缩文件哈希并记录到区块链]
    D --> E[Base64 编码]
    E --> F[计算编码哈希并记录到区块链]
    F --> G[分割为数据块]
    G --> H[为每个数据块生成带元数据的二维码]
    H --> I[计算二维码数量哈希并记录到区块链]
    I --> J[循环显示二维码]
    J --> K[结束]

步骤详解

1. 任务初始化

首先生成唯一的任务ID,用于标识整个传输任务。任务ID可以通过配置文件选择随机生成或自定义模式。

def generate_task_id(self):
    task_id_mode = config_manager.get('General', 'TaskIDMode', 'random')
    if task_id_mode == 'custom':
        custom_task_id = config_manager.get('General', 'CustomTaskID', '')
        if custom_task_id:
            return custom_task_id
    return f"TASK-{uuid.uuid4().hex[:8].upper()}"

Sources: send.py

2. 文件压缩

使用 zipfile 模块将输入文件或目录压缩为 zip 格式,压缩级别可通过配置文件调整。

def compress(self, input_path, output_path=None):
    # ...
    with zipfile.ZipFile(output_path, 'w', compression=zipfile.ZIP_DEFLATED, 
                        compresslevel=self.compression_level) as zipf:
        if os.path.isfile(input_path):
            zipf.write(input_path, os.path.basename(input_path))
        else:
            for root, dirs, files in os.walk(input_path):
                for file in files:
                    file_path = os.path.join(root, file)
                    arcname = os.path.relpath(file_path, input_path)
                    zipf.write(file_path, arcname)
    # ...

Sources: modules/compressor.py

压缩完成后,计算压缩文件的哈希值并添加到区块链中进行记录,确保数据完整性。

3. Base64 编码

将压缩后的文件转换为 Base64 编码字符串,便于在二维码中传输。

def encode_file(self, file_path):
    with open(file_path, 'rb') as f:
        data = f.read()
        base64_str = base64.b64encode(data).decode('utf-8')
    return base64_str

Sources: modules/encoder.py

同样,计算 Base64 字符串的哈希值并记录到区块链中。

4. 数据分块

将 Base64 编码字符串按照配置的块大小分割为多个数据块,确保每个数据块能适应单个二维码的容量限制。

def split_into_blocks(self, base64_str, block_size=None):
    if block_size is None:
        block_size = self.block_size

    num_blocks = (len(base64_str) + block_size - 1) // block_size
    blocks = [base64_str[i*block_size : (i+1)*block_size] for i in range(num_blocks)]

    return blocks

Sources: modules/encoder.py

5. 二维码生成

为每个数据块生成一个二维码,二维码中包含元数据(任务ID、总块数、当前块号、数据块哈希)以便接收端验证和重组。

def generate_qr_code(self, task_id, total_blocks, current_block, data_block, output_path):
    block_hash = self.validator.calculate_hash(data_block)

    qr_data = {
        'task_id': task_id,
        'total_blocks': total_blocks,
        'current_block': current_block,
        'data_block': data_block,
        'block_hash': block_hash
    }

    qr_json = json.dumps(qr_data, ensure_ascii=False)

    qr = qrcode.QRCode(
        version=self.version if self.version > 0 else None,
        error_correction=self.error_correction,
        box_size=self.box_size,
        border=self.border,
    )

    qr.add_data(qr_json)
    qr.make(fit=True)

    img = qr.make_image(fill_color="black", back_color="white")
    img = img.resize((self.size, self.size), Image.LANCZOS)
    img.save(output_path, format=self.format)

Sources: modules/qrcode_generator.py

生成所有二维码后,记录二维码数量的哈希值到区块链中。

6. 二维码显示

使用 tkinter 创建窗口循环显示所有生成的二维码,方便接收端逐个扫描。显示间隔可通过配置文件调整。

def show_multiple_qr(self, qr_paths, task_id="", total_size=0):
    # 创建窗口和标签
    # ...

    # 启动显示线程
    self.is_running = True
    self.thread = threading.Thread(target=self._cycle_display, args=(qr_paths, task_id, total_size))
    self.thread.daemon = True
    self.thread.start()

    self.root.mainloop()

Sources: modules/displayer.py

相关配置

二维码生成流程涉及以下主要配置项(可在 config.ini 中调整):

配置段 配置项 说明 默认值
General TaskIDMode 任务ID生成模式(random/custom) random
Compression CompressionLevel 压缩级别(0-9) 9
QRCode BlockSize 每个数据块的大小(字符数) 2000
QRCode Version 二维码版本(1-40,0为自动) 1
QRCode ErrorCorrection 纠错级别(L/M/Q/H) H
QRCode Size 生成的二维码图片尺寸(像素) 600
QRCode BoxSize 二维码模块大小(像素) 10
QRCode Border 二维码边框大小 4
QRCode DisplayInterval 循环显示间隔(秒) 2

下一步

了解了二维码生成流程后,您可以查看以下相关文档: - 二维码读取流程 - 了解如何读取和解析二维码 - 数据完整性验证 - 深入了解数据完整性保障机制 - 压缩与编码机制 - 详细了解压缩和编码实现