php qqwry.dat_利用PHP或者python實現純真資料庫qqwry.dat的自動更新

5da2480cca562017038530457b24352b.png

純真資料庫qqwry.dat的歷史很悠久了,到底多少年也算不清了,只記得它比QQ顯IP還早,一直到現在很多IP搜尋網站還是使用的純真資料庫qqwry.dat,並且qqwry.dat也一直在更新,但是純真網路的qqwry資料庫要採用setup.exe安裝,對於自動更新資料庫來說不太方便,這裡收集到兩種方法實現定時自動更新純真資料庫qqwry.dat。

自動更新純真資料庫qqwry.dat的原理是:從copywrite.rar中讀取解密需要的key,然後解密qqwry.rar頭0x200位元組資料,然後使用zlib解壓資料即可得到qqwry.dat檔案。透過程式碼可以實現純真資料庫的自動更新工具。另外copywrite.rar中還有一些更多的資料,例如版本號、qqwry.rar檔案大小,這裡沒有全部列出。

一、PHP程式碼實現自動更新純真資料庫qqwry.dat

$copywrite = file_get_contents("http://update.cz88.net/ip/copywrite.rar");

$qqwry = file_get_contents("http://update.cz88.net/ip/qqwry.rar");

$key = unpack("V6", $copywrite)[6];

for($i=0; $i<0x200; $i++)

{

$key *= 0x805;

$key ++;

$key = $key & 0xFF;

$qqwry[$i] = chr( ord($qqwry[$i]) ^ $key );

}

$qqwry = gzuncompress($qqwry);

$fp = fopen("qqwry.dat", "wb");

if($fp)

{

fwrite($fp, $qqwry);

fclose($fp);

}

?>

二、python程式碼實現自動更新純真資料庫qqwry.dat

# coding=utf-8

#

# 用於從純真網路(cz88.net)更新qqwry.dat

# for Python 3.0+ #

# 用法:

# from cz88update import updateQQwry

# result = updateQQwry(filename)

#

# ?當引數filename是str型別時,表示要儲存的檔名。

# 成功後回傳一個正整數,是檔案的位元組數;失敗則回傳一個負整數。

#

# ?當引數filename是None時,函式直接回傳qqwry.dat的檔案內容(一個bytes物件)。

# 成功後回傳一個bytes物件;失敗則回傳一個負整數。這裡要判斷一下回傳值的型別是bytes還是int。

#

# 負整數表示的錯誤:

# ?-1:下載copywrite.rar時出錯

# ?-2:解析copywrite.rar時出錯

# ?-3:下載qqwry.rar時出錯

# ?-4:qqwry.rar檔案大小不符合copywrite.rar的資料

# ?-5:解壓縮qqwry.rar時出錯

# ?-6:儲存到最終檔案時出錯

import struct

import urllib.request

import zlib

__all__ = ('updateQQwry',)

def updateQQwry(filename):

def get_fetcher():

# no proxy

proxy = urllib.request.ProxyHandler({})

# opener

opener = urllib.request.build_opener(proxy)

def open_url(url):

# request物件

req = urllib.request.Request(url)

ua = ('Mozilla/5.0 (Windows NT 6.1; rv:38.0)'

' Gecko/20100101 Firefox/38.0')

req.add_header('User-Agent', ua)

try:

# r是HTTPResponse物件

r = opener.open(req, timeout=60)

return r.read()

except Exception as e:

return None

return open_url

fetcher = get_fetcher()

# download copywrite.rar

url = 'http://update.cz88.net/ip/copywrite.rar'

data = fetcher(url)

if not data:

return -1

# extract infomation from copywrite.rar

if len(data) <= 24 or data[:4] != b'CZIP':

return -2

version, unknown1, size, unknown2, key =

struct.unpack_from('

if unknown1 != 1:

return -2

# download qqwry.rar

url = 'http://update.cz88.net/ip/qqwry.rar'

data = fetcher(url)

if not data:

return -3

if size != len(data):

return -4

# decrypt

head = bytearray(0x200)

for i in range(0x200):

key = (key * 0x805 + 1) & 0xff

head[i] = data[i] ^ key

data = head + data[0x200:]

# decompress

try:

data = zlib.decompress(data)

except:

return -5

if filename == None:

return data

elif type(filename) == str:

# save to file

try:

with open(filename, 'wb') as f:

f.write(data)

return len(data)

except:

return -6

else:

return -6

if __name__ == '__main__':

import sys

if len(sys.argv) > 1:

ret = updateQQwry(sys.argv[1])

if ret > 0:

print('成功更新到%s,%s位元組' %

(sys.argv[1], format(ret, ','))

)

else:

print('更新失敗,錯誤程式碼:%d' % ret)

else:

print('用法:以想要儲存的檔名作引數。')

參考資料:

https://github.com/shuax/QQWryUpdate

https://pypi.python.org/pypi/qqwry-py3