多谢 http://blog.sina.com.cn/hathuang" 小石的博客 启发,苦钻几天转换很多方法跌过很多的坑又爬起才完善破解。
1.编码:
创建字节概率表,记录字节所在区间值(字节出现次数表中的hf结束位-of开始位置,)。如字节出现次数的序列,例如asdfssf 串中s(0-3)f(3-5)a(5-6) d(6-7);
2.用一个影射区(相当于磁带接信息),遍历全部数组的操作中,每个字节取出对应表中区间值(出现次数)将其左移直到(of减去hf大于总字节数),影射区接收 左移中溢出位,
如果概率大(出现次数多) 移动很小位, 就使其值的区间大于总数,如果只出现1 次,即要移动最多的位才大于总数,也就是相似信息熵的概念。
3.影射区保在全部溢出的位以及剩下操作过区间值的数位(在影射区中所有的位的信息也就是of开始位置数的叠加,但它有序的二进制数据)。
4.解压过程:初始化概率表,
a 用第1个字节其对应表中开始位数of,结束位数hf,同样地左移直到hf-of大于总数,与止同时左移压宿数据,减去移位后的of剩下值就是下一个解压 字节在概率表中区间中,查找该值在表中所在区间,解压的字节就是表中对应的字节,也就是分离前靣叠加数据,此时of取查找出表对应区间开始数of,hl等于该区间结束数hl,重复a,每次左移一位,在压宿的数据取出一位,一直循环到结束。
!!!特必注意的是初始时,在压宿的字节组最先要多少位,这要和编码时记录的溢出的位相对应。
如有sasdaadhn字符串,在概率表
开始位置 | 本结束位置 | 概率(出现数)///需要移动 |
---|---|---|
a(1-4)///00000001 | 0000100 | 32 |
s(4-6)///0000100 | 00000110 | 2///3 |
d(6-8)///00000110 | 00000110-00001000 | 2///3 |
h(8-9)//00001000 | 00001000-00001001 | 1///4 |
n(9-10)//00001001 | 00001001-00001010
| 1///4 |
of-hf>总数9 移位后结束后影射区同步左移 | 开始位置 |
00000000000000000000000000100000加s开如位置(00000100)移3位为00100000 | s+00000100 |
00000000000000000000000010000100加 a开始位(00000001)移2位(00000100) | a+00000001 |
00000000000000000000010001000000加 s(00000100)移3位加(00100000) | s+00000100 |
00000000000000000010001000110000加 d(00000110)移动3位(00110000) | d+00000110 |
00000000000000001000100011000100加 a(00000001)移2位(00000100) | a+00000001 |
0000000000000100010001100010100加 a(00000001)移2位(00000100) | a+00000001 |
0000000000100010001100011010000加 d(00000110)移3位(00110000) | d+00000110 |
0000001000100011000110110000000加 h(00001000)移4位(10000000) | h+00001000 |
0010001000110001101100010010000加 n(00001001)移4位(10010000) | n+00001001 |
上表最后1行即是压宿数据。或者说字节在概率表开始位置数浓宿值的叠加,其间左移了26位为了字节对齐,为了字节数对齐还要左移6位得到,00000100,01000110,00110110,00100100,00000000 压缩数据 00000100|010001100011011000100100 第1个字节of值00000100 s左移3位 压缩数 00000100010|001100011011000100100 of值 00000100000 相减=00000010 即2,查找概率表属于1-4区间中,对应字符a,取该区间of 1, 压缩数 00000010|001100011011000100100 of值 00000001 a左移2位后 压缩数 00001000|1100011011000100100 of值 00000100 相减=00000100 即4,属于4-6区间对应字符s,取该区间of=4, 压缩数 00000100|1100011011000100100 of值 00000100 s左移3位后 压缩数 00100110|0011011000100100 of值 00100000 相减=6,属于6-8区间,字符d,of=110, 压缩数 00000110|0011011000100100 of值 00000110 d左移3位 压缩数 00110001|1011000100100 of值 00110000 相减=1,属于1-4区间,字符a,of=1, 数据 00000001|1011000100100 of 00000001 a左移2位后 数据 00000110|11000100100 of值 00000100 相减=2,属于1-4区间,字符a,of=1, 数据 00000010|11000100100 of值 00000001 a左移2位 数据 00001011|000100100 of 00000100 相减=7,属于6-8区间,字符d,of=6, 数据 00000111|000100100 of 00000110 d左移3位 数据 00111000|100100 of 00110000 相减=8,属于8-9区,字符h,of=8 数据 00001000|100100 of 00001000 h左移4位 数据 10001001|000000 of 10000000 相减=9,属于9-10区间,字符n
解 码过程用前数同样同步左移直到hf-of>总数,影射数据-of剩下即是下1个字节所属区间,取该位置of移位直到大于总数,用影射区数-of得下一个开始位数,直到结束,因为压宿数据中重叠成分,左移后减去了 前一个of同步左移即是该字节在概率表位置,也是压宿后数组保在第一字节数可得对应of和hf。同样保存概率表信息
更详细代码 html://lue62.cn:8080/index.html