您的位置:首页 > 编程语言 > Python开发

[原创]python获取swf的宽和高

2011-02-22 12:06 316 查看
swf格式其实是公开的,据说在adobe的官网上有,不过我没找到,感兴趣的同学去找原文阅读,因为项目只需要提取出swf的宽和高,所以只作相关分析。

00000000: 4357 5308 483a 0500 789c 7cbb 6554 5c4d
00000010: d335 7c70 770d eeee 1adc dd1d 0602 c1dd
首先载入我们的swf. 切换到十六进制方式。我们需要的宽和高信息就在上面的字节序列里,其中

头3个字节内容为43 57 53  或 46 57 53。  其中43 57 53 代表的是cws,也就是这个Swf是压缩过的。而46 57 53代表的是fws,也就是这个swf是未压缩过的。本次实验中使用的flash基本上是cws的。如果新建一个空白fla,再导出swf的话。那么头部就是fws的。同学们可以自己实验下。这3个字节对于我们来说的作用是cws的swf我们需要对其内容进行解压缩。而这种压缩方式就是标准的zlib格式。而fws的我们直接就可以分析了。

接下来的5个字节08 48 3a 05 00我们忽略不计,里面包含了flash的版本号和其它信息,感兴趣的同学自己看看。

最关键的是78 9c 7c bb 65 54 5c 4d  d3这里9个字节,里面包含的是宽和高的信息。这里是要运算得到的。注意我们不能直接拿来运算,先由头3个字节来确定,flash是否是压缩过的,如果是压缩过的,那么这9个字节是不能直接运算的,要先解压缩为fws格式,才能运算。

新格式为: 46 57 53 + 原头部08 48 3a 05 00这5个字节 +  从这里9个字节开始至文件尾的数据以zlib格式解压缩。 这样就是新文件格式了,不懂的同学看最后面的py源码。
这里只需要知道如果是cws的,那么要先解压缩就可以了。附上解压后的头部:
00000000: 4657 5308 483a 0500 8000 0272 e000 00a4  FWS.H:…..r….
00000010: 6000 2d08 0044 1100 0000 0043 0200 0000  `.-..D…..C….
下面就可以开始分析了。
包含宽高信息的9个字节:80 00 02 72 e0 00 00 a4  60
把每个字节的十六进制值转为二进制码,不足8位的头部补0:
0×80 = 10000000
0×00 = 00000000
0×02 = 00000010
0×72 = 01110010
0xe0 = 11100000
0×00 = 00000000
0×00 = 00000000
0xa4 = 10100100
0×60 = 01100000
把2进制码连成新字串得到:
100000000000000000000010011100101110000000000000000000001010010001100000
去掉头部5位,形成新字串:
0000000000000000010011100101110000000000000000000001010010001100000
每15位分隔字串,得到5组,丢弃最后一组。
000000000000000
001001110010111
000000000000000
000000101001000
1100000
留下的4组其中第2和第4组就是宽和高,但并不是最终的
(001001110010111)2 = (5015)10
(000000101001000)2 = (328)10
最终的宽和高要依据9个字节的第一个字节来确定是哪种类型的,比如
80 00 02 72 e0 00 00 a4  60这里首字节是80,那么最终宽高应该是
w = 5015 / 5 = 1003
h = 328 / 1.24 = 264  (取整,和dw相比有一点偏差)
如果首字节是78,那么就要各除以20,才是最终的宽和高。
如果首字节是70,那么上面所有的算法不成立,这个还没有分析出来,因为项目使用的flash没有这种情况。

如果表述的不详细的地方,请结合参考资料和源代码理解。如果有任何意义请留言提出。谢谢。
附上python源代码:
#-*- coding:utf-8
#write by  script@HKCAT.ORG
import zlib
import binascii
from StringIO import StringIO

#计算宽高
class swfWHMath:
width=0;
height=0;
hexvalue = hex(0);
def getWidth(self):
return self.width;

def getHeight(self):
return self.height;

def getHex(self,f):
fdHex = file(f.name,"rb");
fdHex.seek(8,0);
self.hexvalue = fdHex.read(9);
fdHex.close();
return self.hexvalue;

def addzero(self,s):
a = len(s);
n=s;
for i in range(0,8-a):
n = '0' + n;
return n;

def returnWH(self):
dff = self.hexvalue;
s=  binascii.b2a_hex(dff);
j = 2;
i = 0;
s_bin = "";
for n in range(0,9):
s_bin = s_bin + self.addzero(hex2bin(s[i:j]));
i = i +2;
j = i + 2;
s3 = s_bin[20:35]; #22: 37
s5 = s_bin[50:65]; #50:65
r1 = bin2dec(s3);
r2 = bin2dec(s5);
if s[0:2] == '80':
self.width = int(r1) / 5;
self.height = int(int(r2) / 1.24);
elif s[0:2] == '78':
print "78";
self.width = int(r1) / 20;
self.height = int(r2) / 20;
else:
#70的未分析
print "未知swf类型:%s" %  s[0:2];
print "W字串值:%d" % int(r1);
print "H字串值:%d" % int(r2);

#swf解压缩类
class swfDecompress:
path="";
magic_cws = "CWS";
magic_fws = "FWS";
def check(self,f):
f.seek(0,0);
magic = f.read(3);
if magic == self.magic_cws:
return True;
elif magic == self.magic_fws:
return False;
else:
return None;

def unzip(self,f):
data = "FWS"+f.read(5)+zlib.decompress(f.read());
tmpf = file("tmp.swf","wb");
tmpf.write(data);
tmpf.close();
return tmpf;

# base = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F]
base = [str(x) for x in range(10)] + [ chr(x) for x in range(ord('A'),ord('A')+6)]

# bin2dec
# 二进制 to 十进制: int(str,n=10)
def bin2dec(string_num):
return str(int(string_num, 2))

# hex2dec
# 十六进制 to 十进制
def hex2dec(string_num):
return str(int(string_num.upper(), 16))

# dec2bin
# 十进制 to 二进制: bin()
def dec2bin(string_num):
num = int(string_num)
mid = []
while True:
if num == 0: break
num,rem = divmod(num, 2)
mid.append(base[rem])

return ''.join([str(x) for x in mid[::-1]])

# dec2hex
# 十进制 to 八进制: oct()
# 十进制 to 十六进制: hex()
def dec2hex(string_num):
num = int(string_num)
mid = []
while True:
if num == 0: break
num,rem = divmod(num, 16)
mid.append(base[rem])

return ''.join([str(x) for x in mid[::-1]])

# hex2tobin
# 十六进制 to 二进制: bin(int(str,16))
def hex2bin(string_num):
return dec2bin(hex2dec(string_num.upper()))

# bin2hex
# 二进制 to 十六进制: hex(int(str,2))
def bin2hex(string_num):
return dec2hex(bin2dec(string_num))

if __name__ == "__main__":
path = "main.swf";
f = file(path,"rb");
sd = swfDecompress();
isZip = sd.check(f);
sm1 = swfWHMath();
if isZip == None:
print "Error swf file format";
exit(0);
if isZip :
tmpf  = sd.unzip(f);
print "CWS:";
hexw  = sm1.getHex(tmpf);
else:
print "FWS:";
hexw =  sm1.getHex(f);
#print hexw;
sm1.returnWH();
print sm1.getWidth();
print sm1.getHeight();
f.close();


本文首发于http://www.hkcat.org/407.html,转载请带上链接,谢谢

4000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python hex string flash file path