原文链接(http://blog.csdn.net/xingtian713/article/details/4483810)
在Chrome中有一个很有意思的工具courgette,翻译成中文是小胡瓜的意思。我很难把这个单词和这个小工具联系在一起,也许作者比较偏爱这个蔬菜吧!

背景

我们用C++编写程序时,经常会出现修改了一行代码,重新编译一下之后,再去对比一下新的二进制文件,就可以发现千差万别了。往往出现我们要发布一个修改了一行代码的补丁,需要替换整个DLL或者EXE。这对于Chrome中类似于Chrome.dll(10M左右)文件来说,升级一次的代价还是挺高的。本人在去年下半年负责的一个升级服务器项目中,就曾动过念头,是否有一种方法可以寻找出两个二进制文件的差异,将这个差异打成一个补丁,用户下载后,可以通过这个补丁,可以自动生成新的DLL。可惜功力不够,最后放弃了。最近读Chrome的代码时,发现Chrome已经实现了该功能。这个就是Courgette的功劳了。

Courgette做什么的?

Courgette主要用于Chrome的升级过程,他的主要作用是,针对两个版本不同的二进制文件(Binary File),寻找其中区别,生成补丁文件;另外就是根据这个补丁文件加上旧版本的二进制文件生成新版本的二进制文件的还原过程了。类似于加解密流程。

Courgette的实现原理?

Courgette构建在一个开源代码bsdiff和bspatch 基础上的。并在bsdiff的基础上做了一些优化。

本人是半路出家的人,对编译原理和汇编了解不深,按照我对bsdiff的算法 理解,一个二进制文件里面,包含了代码部分(函数,数据),指向这些函数的指针列表(编译链接产生,包含了如何定位函数等信息),由于这些地址是内部的相对地址,即使更改了一小行代码,重新编译后,函数的地址将发生变化了,指向这些函数的指针值也全部变化了。因此,即使更改了一个小小的变量,也会导致很多部分的修改。bsdiff的原理就是对二进制文件进行反汇编,将上面所说的两部分进行分别处理,对于代码部分,其实就和普通的文本文件类似了,改变不会太大,这部分体积基本上占去了整个二进制文件的80%左右。然后对动态指针部分进行一些更新处理,就基本上达到了打补丁的目标了。

server:
        diff = bsdiff(original, update)
        transmit diff
    client:
        receive diff
        update = bspatch(original, diff) 
大致流程如上,制作补丁时调用bsdiff函数,根据两个不同版本的二进制文件,生成补丁文件。客户端下载补丁后,调用bspatch函数,根据旧版本二进制文件和补丁生成新的二进制文件。

Chrome在bsdiff的基础上做了一些优化,主要体现在动态指针列表部分,chrome对代码部分的每一个模块地址分配了一个标签(Label),这些标签都是整数,并把这些标签保存到一个数组中,然后指针列表中映射的地址改为指向数组的索引,由于一些函数地址被调用多次,通过这种方法确实可以减少一些体积。做了一些优化后,在bsdiff的基础上又减少了30%左右吧(这是google的说法,我没验证过)。

    server:
        asm_old = disassemble(original)
        asm_new = disassemble(update)
        asm_new_adjusted = adjust(asm_new, asm_old)
        asm_diff = bsdiff(asm_old, asm_new_adjusted)
        transmit asm_diff

    client:
        receive asm_diff
        asm_old = disassemble(original)
        asm_new_adjusted = bspatch(asm_old, asm_diff)
        update = assemble(asm_new_adjusted)

Chrome的大致处理流程如上,和bsdiff流程类似,多了  asm_new_adjusted = adjust(asm_new, asm_old)这一个步骤,这个步骤主要就是上面说的对地址标签化的过程。

Chrome的小胡瓜(Courgette)相关推荐

  1. courgette(小胡瓜)测试报告

    背景 最近的省流量更新很火,一个10几M的包用3M多的增量包就能完成更新.主要原理是利用原包与更新包做比对并生成增量包.普通的做法都是用bsdiff来生成增量包并用bspatch做合包,但大家都说还有 ...

  2. 【Android-功能】Android应用增量更新

    很久没有更新博客了,真是堕落啊,几次想提起笔,却总是被各种琐事耽搁,以后会多写文章记录点滴. 背景 随着android应用体积的不断增大,以及应用版本发布的不断更迭,用户的升级成了一个问题,googl ...

  3. 开源我的基于字节的数据补丁算法库HDiffPatch

    开源我的基于字节的数据补丁算法库HDiffPatch 作者: HouSisong@GMail.com   2013.05.31 tag: HDiffPatch,diff,patch,补丁 HDiffP ...

  4. 常用英语食品词汇- 蔬菜类

    daikon     白萝卜 daikon  ['daikən] carrot     胡萝卜 carrot  ['kærət] radish     萝卜 radish  ['rædiʃ] pars ...

  5. 软件升级:Courgette(小胡瓜)

    原文链接:http://www.feelcomes.com/Show.aspx?id=33 正如我在<越小就越快(和越安全)①>中所描述的,我们实现了一种用差异的压缩算法,来使得chrom ...

  6. chrome源代码目录结构简介

    为了对庞大的源码项目进行分析,先对源码目录树作一个简单的介绍,粗略的了解一下各个模块的功能分布情况,chrome源代码src目录下的结构如下图: app:该目录下的代码主要是和各个操作系统平台相关的应 ...

  7. chrome源代码目录结构简介(版本4.1.249.1059)

    为了对庞大的源码项目进行分析,先对源码目录树作一个简单的介绍,粗略的了解一下各个模块的功能分布情况,chrome源代码src目录下的结构如下图: app:该目录下的代码主要是和各个操作系统平台相关的应 ...

  8. Chrome源代码结构

    首先,开始接触Chrome的童鞋可能有一个疑惑,Chrome和Chromium是同一个东西吗?答案是,Chrome是Google官方的浏览器项目名称,Chromium是Google官方对Chrome开 ...

  9. chrome使用的开源工程介绍

    在chrome地址栏输入about:credits就可以看到chrome使用的开源工程了,之前也有一篇介绍chrome开源工程的文章:Code Reuse in Google Chrome Brows ...

最新文章

  1. 会写代码是你创业路上的包袱吗?
  2. LACP链路聚合-基础篇
  3. OS_CORE.C(10)
  4. html表单提交后怎么发送邮箱,Dreamweaver中用表单制作了留言板,如何将内容提交后发到指定邮箱?...
  5. 算法训练 字符串的展开
  6. 微信小程序错误 Cloud API isn‘t enabled, please call wx.cloud.init first 解决
  7. ai电磁组属于什么组_RPA+AI 创新案例挑战赛 2020 【专业组】amp;【校园组】优胜名单来也!...
  8. 做了中台就不会死吗?每年至少40%开发资源是被浪费的!
  9. elasticsearch java 分页查询_elasticsearch深度分页问题
  10. 深度学习之RNN、LSTM及正向反向传播原理
  11. pandas筛选某个列值是否位于某个列表内
  12. 【快代理】开放代理使用教程
  13. python机械臂仿真_如何用ROS+Rviz+Arbotix控制器仿真为六自由度机械臂建模-工业电子-与非网...
  14. ubuntu20.04不是所有者所以不能更改权限
  15. Mac SublimeREPL一点经验
  16. vue 过滤器 首字母大写
  17. 逆天改命,Java 反射的黑科技
  18. YY游戏云的AngularJS实践
  19. 国际海运出口的操作流程是怎样的?
  20. coTurn 运行在Windows平台的方法

热门文章

  1. 高精度 A+B Problem
  2. Oracle 物化视图详解(materialized)
  3. sizeof用法详解
  4. Flume官方文档阅读笔记及实际操作
  5. 连续不一定可导的例子
  6. oracle create database
  7. 面向数据中台的数据治理七把利剑
  8. 为什么朋友圈总有些环游世界的人? 可能大部分是...
  9. 用Python写一个爬虫,爬取双色球开奖记录
  10. 宣传册尺寸+企业宣传册设计要素