QQwry到Sqlite3
来源:互联网 发布:有关网络暴力的视频 编辑:程序博客网 时间:2024/06/06 05:12
QQwry是国内很流行的一个中文IP数据库,它使用特别的格式存储IP记录压缩率很高,正因如此,每次升级数据库时得重新下载整库,我希望让它更简单一点,升级只需要下载批量更新数据,我试着把它转换成sqlite3,
先贴我的代码
Python代码:
'''
Created on 2010-4-17
@author: Ben
@mail: ben.pang.china@gmail.com
'''
import os
import sys
import sqlite3
def binToInt(data):
"""将传入的bytes转换为integer
传入的bytes序列将按编号从低位到高位的排序组转换为integer,如:
data[0]~data[3]分别是:0x00 0x01 0x02 0x03
那么它对应的数值的binary是
00000011 00000010 00000001 00000000
等于十进制数值50462976
"""
x = 0
for i,d in enumerate(data):
x |= d << ( i * 8 )
return x
def readRecord(index):
"""根据传入的索引地址读取该记录的全部信息
根据传入的索引地址读取该IP记录,如其实IP,结束IP,country字段,area字段
"""
def readStr():
"""从指定索引读取出文本内容
从指定索引开始向后检索0,提取出字节并转换为字符信息;索引index引用readRecord的变量index,并且在读取字符后将index指向0
"""
nonlocal index
old,index = index, data.find( b'x00', index ) # 从index位置开始查找0所在位置
return data[ old : index ].decode('gbk')
start_ip = '{}.{}.{}.{}'.format( *reversed(data[ index : index + 4 ]) ) # 将IP字节转换为人可读的IP地址,如: 192.168.1.1
index = binToInt(data[ index + 4 : index + 7 ]) # 获取结束IP的索引地址
end_ip = '{}.{}.{}.{}'.format( *reversed(data[ index : index + 4 ]) ) # 结束IP地址
# 设置索引变量指向指向end ip后的索引处
index += 4
# 判断IP信息的索引模式
if data[ index ] == 0x01:
index = binToInt(data[ index + 1 : index + 4 ]) # 重设索引到新位置
if data[ index ] == 0x02: # 判断country信息是指针还是字符串
old, index = index, binToInt( data[ index + 1 : index + 4 ] ) # 缓存当前索引地址,并将索引变量指向country字符串所在地址
country = readStr() # 读取country信息
index = old + 4 # 将索引指area地址
else:
country = readStr()
index += 1
if data[ index ] == 0x01 or data[ index ] == 0x02:
index = binToInt( data[ index + 1 : index + 4 ] )
area = readStr() # 获取area信息
return [ start_ip, end_ip, country, area ]
# 全局变量,用于存储一些数据库的常量
data = bytes() # 用于缓存数据库内容
cur = None
c_record = {}
a_record = { "" : None }
def convert(db):
"""将IP记录从QQway中检索出来并存入sqlite3数据库中"""
if not os.path.exists(db):
print("Not found db:",db)
return
global data, firstIndex, lastIndex, cur
with open(db,'rb') as f:
data = f.read() # 从数据库中读取字节并进行缓存
firstIndex = binToInt(data[:4])
lastIndex = binToInt(data[4:8])
conn = sqlite3.connect( "ipdb.sdb3" )
cur = conn.cursor()
for i in range(firstIndex, lastIndex, 7):
saveIpRecord( readRecord(i) )
else:
conn.commit()
conn.close()
print("converted and saving to ipdb.sql3")
def saveIpRecord(record):
"""保存IP记录到数据库"""
global cur, c_record, a_record
start_ip, end_ip, country, area = record
if country not in c_record:
cur.execute("INSERT INTO country VALUES(null, ?)", (country, ))
c_record[ country ] = cur.execute("SELECT max(id) FROM country").fetchone()[0]
if area not in a_record:
cur.execute("INSERT INTO area VALUES(null, ?)", (area, ))
a_record[ area ] = cur.execute("SELECT max(id) FROM area").fetchone()[0]
cur.execute("INSERT INTO ipaddr VALUES(null, ?, ?, ?, ?)", ( start_ip, end_ip, c_record[ country ], a_record[ area ] ))
if __name__ == '__main__':
if len(sys.argv) == 2:
convert(sys.argv[1])
else:
print("usage: converter.py database")
你需要先了解QQwry.dat的格式,那么应该看的懂我们代码.生成的sqlite3很大是原来的6倍.
不过这只是测试代码,我还能改进优化存储,应该能至少压缩一半,并加快检索速度.
- QQwry到Sqlite3
- QQwry到Sqlite3(续)
- 导出QQWry.Dat中IP地址到文件[C#]
- SQLite3 移植到 ARM
- sqlite3移植到ARM SQLITE3.7.14
- QQwry格式
- sqlite3移植到arm linux
- sqlite3移植到arm-linux
- sqlite3添加数据库到工程
- django sqlite3迁移到mysql
- SQlite3移植到MTK平台成功!
- 写个Sqlite3到Lua的library
- sqlite3.7.3移植到arm问题
- Sqlite3.78移植到VxWorks6.6
- Project中用到的python和sqlite3
- 移植sqlite3到嵌入式平台上
- Sqlite3.78移植到VxWorks6.6
- perl 批量导入文件到sqlite3
- JfreeChart安装配置
- 解决MyEclipse编辑jsp输入.死机、代码提示死机问题
- 一个通用的泛型 GenericHibernateDao
- 如何写扩张mib
- eclipseSvn插件安装
- QQwry到Sqlite3
- 《精通CSS高级WEB标准解决方案》第五章、对列表应用样式和创建导航条
- A Closer Look at 32-Bit vs. 64-Bit Windows
- Java单例模式
- 使用 CAS 在 Tomcat6 中实现单点登录
- Hibernate的通用dao
- Fedora11下安装Xen4.0
- 《精通CSS高级WEB标准解决方案》第六章:6.1 对数据表格应用样式
- JfreeChart例子生成柱状堆积图