
純真資料庫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