查看: 2181|回复: 0
收起左侧

[原创工具] 纯真ip数据库读取(python)

[复制链接]
python无名氏
发表于 2023-9-26 22:38:29 | 显示全部楼层 |阅读模式
  1. #!/usr/bin/python3
  2. # encoding: utf-8

  3. import socket
  4. import codecs
  5. import mmap
  6. from struct import pack, unpack

  7. class QQWry(object):
  8.     def __init__(self, path):
  9.         self.path = path
  10.         self.db = None
  11.         self.open_db()
  12.         self.idx_start, self.idx_end = self._read_idx()
  13.         self.total = (self.idx_end - self.idx_start) // 7 + 1
  14.     def decode_str(self,old):
  15.         try:
  16.             return old.decode('gbk').encode('utf-8')
  17.         except:
  18.             if old[-1] == b'\x96':
  19.                 try:
  20.                     return old[:-1].decode('gbk').encode('utf-8') + b'?'
  21.                 except:
  22.                     pass

  23.             return 'Invalid'.encode('utf-8')
  24.     def open_db(self):
  25.         if not self.db:
  26.             self.db = open(self.path, 'rb')
  27.             self.db = mmap.mmap(self.db.fileno(), 0, access=1)
  28.         return self.db

  29.     def _read_idx(self):
  30.         self.db.seek(0)
  31.         start = unpack('I', self.db.read(4))[0]
  32.         end = unpack('I', self.db.read(4))[0]
  33.         return start, end

  34.     def version(self):
  35.         ip_end_offset = self.read_offset(self.idx_end + 4)
  36.         a_raw, b_raw = self.read_record(ip_end_offset + 4)
  37.         return self.decode_str(a_raw + b_raw).decode('utf-8')

  38.     def read_ip(self, off, seek=True):
  39.         if seek:
  40.             self.db.seek(off)
  41.         buf = self.db.read(4)
  42.         return unpack('I', buf)[0]

  43.     def read_offset(self, off, seek=True):
  44.         if seek:
  45.             self.db.seek(off)
  46.         buf = self.db.read(3)
  47.         return unpack('I', buf + b'\0')[0]

  48.     def read_string(self, offset):
  49.         if offset == 0:
  50.             return 'N/A1'.encode('utf-8')
  51.         flag = self.get_flag(offset)
  52.         if flag == 0:
  53.             return 'N/A2'.encode('utf-8')
  54.         elif flag == 2:
  55.             offset = self.read_offset(offset + 1)
  56.             return self.read_string(offset)
  57.         self.db.seek(offset)
  58.         raw_string = b''
  59.         while True:
  60.             x = self.db.read(1)
  61.             if x == b'\0':
  62.                 break
  63.             raw_string += x
  64.         return raw_string

  65.     def get_flag(self, offset):
  66.         self.db.seek(offset)
  67.         c = self.db.read(1)
  68.         if not c:
  69.             return 0
  70.         return c[0]

  71.     def read_record(self, offset):
  72.         self.db.seek(offset)
  73.         flag = self.db.read(1)[0]
  74.         if flag == 1:
  75.             buf = self.db.read(3)
  76.             a_offset = unpack('I', buf + b'\0')[0]
  77.             a_raw = self.read_string(a_offset)
  78.             a_flag = self.get_flag(a_offset)
  79.             if a_flag == 2:
  80.                 b_raw = self.read_string(a_offset + 4)
  81.             else:
  82.                 b_raw = self.read_string(a_offset + len(a_raw) + 1)
  83.         elif flag == 2:
  84.             buf = self.db.read(3)
  85.             a_offset = unpack('I', buf + b'\0')[0]
  86.             a_raw = self.read_string(a_offset)
  87.             b_raw = self.read_string(offset + 4)
  88.         else:
  89.             a_raw = self.read_string(offset)
  90.             b_raw = self.read_string(offset + len(a_raw) + 1)
  91.         return a_raw, b_raw

  92.     def output(self, output_file='ip.txt'):
  93.         fp = codecs.open(output_file, 'w', 'utf8')
  94.         idx = self.idx_start
  95.         while idx <= self.idx_end:
  96.             ip_int = self.read_ip(idx)
  97.             ip_start = socket.inet_ntoa(pack('!I', ip_int))
  98.             ip_end_offset = self.read_offset(idx + 4)
  99.             ip_int = self.read_ip(ip_end_offset)
  100.             ip_end = socket.inet_ntoa(pack('!I', ip_int))
  101.             a_raw, b_raw = self.read_record(ip_end_offset + 4)
  102.             a_info = self.decode_str(a_raw)
  103.             b_info = self.decode_str(b_raw)
  104.             fp.write('%15s\t%15s\t%s,%s\n' % (
  105.                 ip_start, ip_end,
  106.                 a_info.decode('utf8'), b_info.decode('utf8')))
  107.             idx += 7
  108.         fp.close()

  109.     def find(self, ip, l, r):
  110.         if r - l <= 1:
  111.             return l
  112.         m = (l + r) // 2
  113.         offset = self.idx_start + m * 7
  114.         new_ip = self.read_ip(offset)
  115.         if ip < new_ip:
  116.             return self.find(ip, l, m)
  117.         else:
  118.             return self.find(ip, m, r)

  119.     def query(self, ip):
  120.         ip = unpack('!I', socket.inet_aton(ip))[0]
  121.         i = self.find(ip, 0, self.total - 1)
  122.         o = self.idx_start + i * 7
  123.         o2 = self.read_offset(o + 4)
  124.         (c, a) = self.read_record(o2 + 4)
  125.         return (self.decode_str(c).decode('utf-8'), self.decode_str(a).decode('utf-8'))

  126.     def __del__(self):
  127.         if self.db:
  128.             self.db.close()

  129. def main():
  130.     dbpath = "qqwry.dat"
  131.     ip = "114.114.114.114"
  132.     qqwry = QQWry(dbpath)
  133.     c, a = qqwry.query(ip)
  134.     print(qqwry.version())
  135.     print('%s %s--%s' % (ip, c, a))

  136. if __name__ == '__main__':
  137.     main()
复制代码
从别人那看到的,原来是python2的,改成python3了
数据库太大了,放不上来,自己找吧

您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

手机版|杀毒软件|软件论坛| 卡饭论坛

Copyright © KaFan  KaFan.cn All Rights Reserved.

Powered by Discuz! X3.4( 沪ICP备2020031077号-2 ) GMT+8, 2024-4-28 02:30 , Processed in 0.136082 second(s), 16 queries .

卡饭网所发布的一切软件、样本、工具、文章等仅限用于学习和研究,不得将上述内容用于商业或者其他非法用途,否则产生的一切后果自负,本站信息来自网络,版权争议问题与本站无关,您必须在下载后的24小时之内从您的电脑中彻底删除上述信息,如有问题请通过邮件与我们联系。

快速回复 客服 返回顶部 返回列表