一种简单的压缩算法
使用环境:简单加密,使用字符串的读取方式,压缩杂项数据
基本原理:也就是把混乱的数据中的00字节去掉。
我想到使用这个压缩方法的时候是为了在文件io很慢的环境下一次性读取较多的文件内容,从而进行的压缩。在很多情况下字符串都是以00结尾的,所以这个压缩的算法只是把数据中的00字节去掉了。当被处理的文件中很多00的时候压缩率较大。但是不适宜对文本,图片之类的压缩。注意,只是简单的压缩,压缩后能够简单的解压缩。在压缩普通数据的时候,大概平均压缩率能够达到 3 :4
E.g. 90 80 29 00 78 98 00 00
这段数据被压缩后的结果是
{ 00 010011 } 90 80 29 78 98 注意只能表示 90 80 29 00 78 98 这6位数据
{}为1byte大小
一看这个列子就很简单了吧
第一byte为标志位。
具体说明
1 全为0位 若数据全为00 则此位为1
E.g. 00 00 00 00 00 00 => 标志位{ 10 000000 }
2 全为1位 若数据全不为00 则此位为1
E.g. 01 02 03 04 05 06 => 标志位{ 01 000000 } 01 02 03 04 05 06
此时数据变大
3-8 位表示该位是否为00 若是则为 1 当 1th 或2ed 不全为0时,可以忽略后面的 3-8位
所以 一个标志位最多能够表示后面的6字节数据,此时消除了数据中的00位,就可以用字符串的读取方式来一次性读取,或者做简单的加密。
一个示例的程序:
是用的步步高学习机的一种叫做BBasic的环境下写的,这个算法其实就是为了应付它io极其的慢的毛病。
这个代码我也只能说表达的是那个意思,如果稍加改造下,大概能够提速10倍 - 100 +倍。
declare function dechex$( decVal)
declare function bindec( binVal$)
'//把所给的一段数据压缩
'//步骤 我先考虑是内存的情况,也就是给出一个位置偏移,然后挨个去读
dim XDB_GetOffset, XDB_GetLen, XDB_GetStr$, XDB_PutFp, XDB_I
dim XDB_GetCur, XDB_AllZ, XDB_AllO
dim Xbd_Offset_Cur
dim XDB_HStr
dim XDB_HCode
dim XDB_GetStr_len
asm
ld int [ vint_XDB_GetOffset], 0
endasm
XDB_GetLen = 7685 - 16
'ab cd 00 39 09 28
'19 08 02 18 00 00
'82 10 00 28 19 00
open "x.txt" for binary as #1
XDB_GetStr_len = 0
XDB_HCode = 0
XDB_GetStr$ = ""
XDB_CStr$ = ""
XDB_HStr$ = ""
t = gettick()
while XDB_I <= XDB_GetLen
locate( 1, 1)
XDB_I = XDB_I + 1
Xbd_Offset_Cur = XDB_I mod 6
if Xbd_Offset_Cur = 0 then
if XDB_AllZ then
XDB_CStr$ = ""
end if
XDB_GetStr + chr + XDB_AllZ )) + XDB_CStr$
XDB_HStr$ = ""
XDB_HCode = 0
XDB_CStr$ = ""
XDB_AllZ$ = "1"
XDB_AllO$ = "1"
XDB_GetStr_len = XDB_GetStr_len + 1
if XDB_GetStr_len > 4088 * 4 then
print XDB_I
put #1, XDB_GetStr$
XDB_GetStr$ = ""
end if
end if
'print "第二步"
asm
ld int [ vint_XDB_GetCur], 0
ld int r0, [ vint_XDB_GetOffset]
ld byte [ vint_XDB_GetCur], [ r0 ]
endasm
'=/当前位为非0
if XDB_GetCur then
XDB_CStr + chr( XDB_GetCur)
XDB_HStr + "0"
'==//全为0的标志位
XDB_AllZ$ = "0"
'=/当前位为0
else
XDB_HStr + "1"
'==//全为1的标志位
XDB_AllO$ = "0"
end if
XDB_GetStr_len = XDB_GetStr_len + 1
'==//一次处理12位
XDB_GetOffset = XDB_GetOffset + 1
wend
print "用时"; gettick() - t
put #1, XDB_GetStr$
put #1, "END"
close #1
asm
jmp QingWuShi_XDB:
XDB_Compression_HCode:
.block 1 0
XDB_Compression_CCode:
.block 6 0
XDB_Compression_Catch:
.block 15 0
XDB_Compression_Base:
endasm
asm
ret
data x bin %abcd00390928190802180000821000281900%
QingWuShi_XDB:
endasm