一、效果展示

二、原理解析
BSDiff的三个基本步骤如下:
1.对old文件中所有子字符串形成一个字典;
2.对比old文件和new文件,产生diffstring和extra string;
3.将diffstring 和extra string 以及相应的控制字用qlz压缩算法压缩成一个patch包。


bsdiff压缩效率实验数据


bsdiff更新数据的基本结构
bsdiff更新数据由四部分组成:Header,ctrl block,diff block,extra block。
Header的结构:

三、源码实现

#ifndef DIFFUPGRADEWIDGET_H
#define DIFFUPGRADEWIDGET_H#include <QVariant>
#include <QApplication>
#include <QGridLayout>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QMainWindow>
#include <QMenuBar>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QStatusBar>
#include <QVBoxLayout>
#include <QWidget>
#include <QFile>
#include <QFileDialog>
#include <QFileInfo>
#include <QDataStream>
#include <QByteArray>
#include <QMessageBox>
#include <QtConcurrent>#define MIN(x,y) (((x)<(y)) ? (x) : (y))#define QLZ_VERSION_MAJOR 1
#define QLZ_VERSION_MINOR 5
#define QLZ_VERSION_REVISION 0#define QLZ_COMPRESSION_LEVEL 3
#define QLZ_STREAMING_BUFFER 0
#define QLZ_MEMORY_SAFE
#define QLZ_BUFFER_PADDING    400
typedef unsigned int ui32;
typedef unsigned short int ui16;// Decrease QLZ_POINTERS for level 3 to increase compression speed. Do not touch any other values!
#if QLZ_COMPRESSION_LEVEL == 1
#define QLZ_POINTERS 1
#define QLZ_HASH_VALUES 4096
#elif QLZ_COMPRESSION_LEVEL == 2
#define QLZ_POINTERS 4
#define QLZ_HASH_VALUES 2048
#elif QLZ_COMPRESSION_LEVEL == 3
#define QLZ_POINTERS 16
#define QLZ_HASH_VALUES 4096
#endif#define MINOFFSET 2
#define UNCONDITIONAL_MATCHLEN 6
#define UNCOMPRESSED_END 4
#define CWORD_LEN 4#if QLZ_COMPRESSION_LEVEL == 1 && defined QLZ_PTR_64 && QLZ_STREAMING_BUFFER == 0
#define OFFSET_BASE source
#define CAST (ui32)(size_t)
#else
#define OFFSET_BASE 0
#define CAST
#endif#define BLOCK_HEADER_SIZE              4#define COMPRESS_BUFFER_SIZE           4096
#define DCOMPRESS_BUFFER_SIZE          4096/* Buffer padding for destination buffer, least size + 400 bytes large because incompressible data may increase in size. */
#define BUFFER_PADDING                 QLZ_BUFFER_PADDINGclass DiffUpgradeWidget : public QWidget
{Q_OBJECT
public:struct bsdiff_stream{void* opaque;void* (*malloc)(size_t size);void (*free)(void* ptr);int (*write)(struct bsdiff_stream* stream, const void* buffer, int size);};struct bsdiff_request{const uint8_t* old;int64_t oldsize;const uint8_t* neww;int64_t newsize;struct bsdiff_stream* stream;int64_t *I;uint8_t *buffer;};struct bspatch_stream{void* opaque;int (*read)(const struct bspatch_stream* stream, void* buffer, int length);};// hash entrytypedef struct{#if QLZ_COMPRESSION_LEVEL == 1ui32 cache;#if defined QLZ_PTR_64 && QLZ_STREAMING_BUFFER == 0unsigned int offset;#elseconst unsigned char *offset;#endif#elseconst unsigned char *offset[QLZ_POINTERS];#endif} qlz_hash_compress;typedef struct{#if QLZ_COMPRESSION_LEVEL == 1const unsigned char *offset;#elseconst unsigned char *offset[QLZ_POINTERS];#endif} qlz_hash_decompress;// statestypedef struct{#if QLZ_STREAMING_BUFFER > 0unsigned char stream_buffer[QLZ_STREAMING_BUFFER];#endifsize_t stream_counter;qlz_hash_compress hash[QLZ_HASH_VALUES];unsigned char hash_counter[QLZ_HASH_VALUES];} qlz_state_compress;#if QLZ_COMPRESSION_LEVEL == 1 || QLZ_COMPRESSION_LEVEL == 2typedef struct{#if QLZ_STREAMING_BUFFER > 0unsigned char stream_buffer[QLZ_STREAMING_BUFFER];#endifqlz_hash_decompress hash[QLZ_HASH_VALUES];unsigned char hash_counter[QLZ_HASH_VALUES];size_t stream_counter;} qlz_state_decompress;#elif QLZ_COMPRESSION_LEVEL == 3typedef struct{#if QLZ_STREAMING_BUFFER > 0unsigned char stream_buffer[QLZ_STREAMING_BUFFER];#endif#if QLZ_COMPRESSION_LEVEL <= 2qlz_hash_decompress hash[QLZ_HASH_VALUES];#endifsize_t stream_counter;} qlz_state_decompress;#endif
public:friend size_t qlz_decompress_core(const unsigned char *source, unsigned char *destination, size_t size, DiffUpgradeWidget::qlz_state_decompress *state, const unsigned char *history);explicit DiffUpgradeWidget(QWidget *parent = nullptr);private:void value_init();void control_init();//生成差分文件void split(int64_t *I,int64_t *V,int64_t start,int64_t len,int64_t h);void qsufsort(int64_t *I,int64_t *V,const uint8_t *old,int64_t oldsize);int64_t matchlen(const uint8_t *old,int64_t oldsize,const uint8_t *neww,int64_t newsize);int64_t search(const int64_t *I,const uint8_t *old,int64_t oldsize,const uint8_t *neww,int64_t newsize,int64_t st,int64_t en,int64_t *pos);void offtout(int64_t x,uint8_t *buf);int bsdiff_internal(const struct bsdiff_request req);int bsdiff(const uint8_t* old, int64_t oldsize, const uint8_t* neww, int64_t newsize, struct bsdiff_stream* stream);int64_t writedata(struct bsdiff_stream* stream, const void* buffer, int64_t length);static int bz2_write(struct bsdiff_stream* stream, const void* buffer, int size);bool create_diff_file(QString oldFilePAN,QString newFilePAN,QString diffFilePAN);//恢复源文件int64_t offtin(uint8_t *buf);int bspatch(const uint8_t* old, int64_t oldsize, uint8_t* neww, int64_t newsize, struct bspatch_stream* stream);static int bz2_read(const struct bspatch_stream* stream, void* buffer, int length);bool recover_bspatch_file(QString oldFilePAN,QString diffFilePAN,QString bspatchFilePAN);//压缩size_t qlz_compress(const void *source, char *destination, size_t size, qlz_state_compress *state);size_t qlz_decompress(const char *source, void *destination, qlz_state_decompress *state);int qlz_get_setting(int setting);bool compress_file(QString srcFilePAN,QString destFilePAN);bool decompress_file(QString srcFilePAN,QString destFilePAN);//创建升级文件bool create_upgrade_file(QString fileNameAndPath);bool recover_upgrade_file(QString fileNameAndPath);
private slots:void btn_click_slot();void watcher_create_finish_slot();void watcher_recover_finish_slot();
private:QGridLayout *gridLayout;QVBoxLayout *verticalLayout;QGroupBox *groupBox;QGridLayout *gridLayout_2;QPlainTextEdit *plainTextEditOld;QHBoxLayout *horizontalLayout;QGroupBox *groupBox_2;QGridLayout *gridLayout_3;QHBoxLayout *horizontalLayout_2;QLabel *label;QLineEdit *lineEditCreateOld;QPushButton *btnCreateOld;QHBoxLayout *horizontalLayout_3;QLabel *label_2;QLineEdit *lineEditCreateNew;QPushButton *btnCreateNew;QPushButton *btnCreate;QLabel *labelCreate;QGroupBox *groupBox_3;QGridLayout *gridLayout_4;QHBoxLayout *horizontalLayout_4;QLabel *label_4;QLineEdit *lineEditRecoverOld;QPushButton *btnRecoverOld;QHBoxLayout *horizontalLayout_5;QLabel *label_5;QLineEdit *lineEditRecoverDiff;QPushButton *btnRecoverDiff;QPushButton *btnRecover;QLabel *labelRecover;QGroupBox *groupBox_4;QGridLayout *gridLayout_5;QHBoxLayout *horizontalLayout_6;QLabel *label_7;QLineEdit *lineEditUpgrade;QPushButton *btnUpgradeSelect;QHBoxLayout *horizontalLayout_7;QPlainTextEdit *plainTextEditUpgrade;QPushButton *btnUpgrade;QLineEdit *lineEditCreateFileName;QHBoxLayout *horizontalLayout_8;QLabel *label_8;QLineEdit *lineEditRecoverFileName;QHBoxLayout *horizontalLayout_9;QLabel *label_9;QString createOldFile = nullptr;QString createNewFile = nullptr;QString createDiffFile = nullptr;QString recoverOldFile = nullptr;QString recoverBspatchFile = nullptr;QString recoverDiffFile = nullptr;QFutureWatcher<bool> watcherCreateDiff,watcherRecoverBspatch;
};#endif // DIFFUPGRADEWIDGET_H

完整工程文章末尾下载
四、完整qt工程下载
点击下载

Qt移植bsdiff算法计算差分文件相关推荐

  1. Qt 之 WAV文件属性计算(比特率、文件大小、文件时长)

    简述 在 Qt 之 WAV文件解析 中给出了WAV文件属性的计算,具体包括文件大小.音频时长.比特率等属性,这里我们再次验证一下这些属性值的计算 . 在计算之前,我们要知道一下wav文件中的三个参数 ...

  2. 四、基于海思芯片:从算法到移植 生成海思wk文件并进行成果展示

    一.基于海思芯片:从算法到移植  darknet框架下训练yolov3 二.基于海思芯片:从算法到移植   darknet框架下yolov3转为caffe框架下 三.基于海思芯片:从算法到移植   c ...

  3. linux qt 5移植,Qt 5.13支持处理Lottie文件,可以方便地进行移植

    Qt 5.13工具包将于5月发布,其中一个重要的特性就是对Lottie文件的支持. BodyMovin插件是一个After Effects插件,它将动画导出为JSON格式,可以在Web上运行.Airb ...

  4. bsdiff php,Apk差分升级Android客户端和Node.js服务端实现

    核心的内容是bsdiff和bspatch 源码根目录/bootable/recovery/applypatch下找到,bsdiff官网同样也是可以的,编出来的二进制文件可以在源码根目录out/host ...

  5. 智能优化算法之 差分进化算法

    差分进化算法原理 差分进化算法是一种随机的启发式搜索算法,简单易用,有较强的鲁棒性和全局搜索能力. 差分进化算法是一种自组织最小化方法,利用种群中随机选择的不同向量来干扰一个现有向量,种群中的每个向量 ...

  6. Qt 移植到Android

    Qt 移植到Android 移植到Android 移植到Android 在本节中,我们将现有的Qt应用程序移植到Android并将其部署到设备. 大多数Qt应用程序应易于移植到Android,除非它们 ...

  7. 嵌入式成长轨迹34 【嵌入式学习阶段】【ARM环境调试】【QT 移植环境及简单程序示例】---补充《ok6410 Qt移植百科全书》...

    更新版 http://www.cnblogs.com/zeedmood/archive/2012/12/08/2808393.html 书上提及的有这些,分别说明下,里边打*可以不弄:   Tslib ...

  8. POJ3169 Layout , 最短路算法解差分约束问题

    POJ3169 Layout 题意: n头牛编号为1到n,按照编号的顺序排成一列,每两头牛的之间的距离 >= 0.这些牛的距离存在着一些约束关系:1.有ml组(u, v, w)的约束关系,表示牛 ...

  9. Atitit 算法之道 attilax著 1. 编码算法 3 1.1. Base64 htmlencode urlencode 3 2. Ui方面的算法 3 2.1. 软键盘算法 计算软键盘上下

    Atitit 算法之道 attilax著 1. 编码算法 3 1.1. Base64 htmlencode  urlencode 3 2. Ui方面的算法 3 2.1. 软键盘算法  计算软键盘上下左 ...

最新文章

  1. 学习笔记:腾讯云--域名解析
  2. html5 图形化操作,HTML5的图像及动画图形操作-20210525222751.ppt-原创力文档
  3. golang 函数 传入返回 slice/map/struct 本质
  4. 必须采用初始化列表一共有三种情况
  5. Database之SQLSever:SQLSever基础知识进阶、软件安装注意事项、软件使用经验总结之详细攻略
  6. 创建虚拟机、安装CentOS 7
  7. 好公司和差公司的对比
  8. AJAX(七)jsonp实战--天气预报
  9. 腾达ap设置说明_腾达(Tenda)F6无线信号放大模式(Client+AP)设置教程 | 192路由网
  10. 强化学习三、策略迭代与值迭代
  11. keil5打开工程文件显示空白bug
  12. Win11鼠标右键默认显示更多,保持跟Win10一致
  13. 南大计算机学院有几个院士,中国大学两院院士数量排名,看看谁的科研实力最强...
  14. 椭圆光学性质的几何证明
  15. 机器学习之性能度量指标——决定系数R^2、PR曲线、ROC曲线、AUC值、以及准确率、查全率、召回率、f1_score
  16. 2019我获得的些许成绩,能不能弥补这一年光阴的流逝?盘点2019我的得失
  17. linux下 文件排序,把 Linux 上的文件列表和排序玩出花来
  18. 我的新浪微博之旅(一)
  19. 人手必备神器——Infinity插件
  20. 实习程序员帮上级“背锅”成习惯,转正后还来?实习生没人权啊!

热门文章

  1. 1、pth转onnx模型、onnx转tensorrt模型、python中使用tensorrt进行加速推理(全网最全,不信你打我)
  2. 想骂人!开发语言不能统一成一个么?
  3. 多账号统一登录实现方案
  4. 一次segfault错误的排查过程
  5. 阿里云块存储企业级特性之异步复制
  6. 读书是在丰富你,读你自己
  7. 易中天:讲《从老庄到禅宗》
  8. 外贸跨境电商必备九款实用APP软件盘点,外贸人必看
  9. 〖Python 数据库开发实战 - Python与MySQL交互篇⑱〗- 项目实战 - 实现用户管理 - 删除用户
  10. 遥感影像变化检测数据集