IPAddress.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import socket
  4. import struct
  5. import logging
  6. logger = logging.getLogger('util')
  7. class IPAddresss:
  8. def __init__(self, ipdbFile):
  9. self.ipdb = open(ipdbFile, "rb")
  10. str = self.ipdb.read(8)
  11. (self.firstIndex, self.lastIndex) = struct.unpack('II', str)
  12. self.indexCount = int((self.lastIndex - self.firstIndex)/7+1)
  13. # print self.getVersion(), u" 纪录总数: %d 条 "%(self.indexCount)
  14. def getVersion(self):
  15. s = self.getIpAddr(0xffffff00)
  16. return s
  17. def getAreaAddr(self, offset=0):
  18. if offset:
  19. self.ipdb.seek(offset)
  20. str = self.ipdb.read(1)
  21. (byte,) = struct.unpack('B', str)
  22. if byte == 0x01 or byte == 0x02:
  23. p = self.getLong3()
  24. if p:
  25. return self.getString(p)
  26. else:
  27. return ""
  28. else:
  29. self.ipdb.seek(-1, 1)
  30. return self.getString(offset)
  31. def getAddr(self, offset, ip=0):
  32. self.ipdb.seek(offset + 4)
  33. countryAddr = ""
  34. areaAddr = ""
  35. str = self.ipdb.read(1)
  36. (byte,) = struct.unpack('B', str)
  37. if byte == 0x01:
  38. countryOffset = self.getLong3()
  39. self.ipdb.seek(countryOffset)
  40. str = self.ipdb.read(1)
  41. (b,) = struct.unpack('B', str)
  42. if b == 0x02:
  43. countryAddr = self.getString(self.getLong3())
  44. self.ipdb.seek(countryOffset + 4)
  45. else:
  46. countryAddr = self.getString(countryOffset)
  47. areaAddr = self.getAreaAddr()
  48. elif byte == 0x02:
  49. countryAddr = self.getString(self.getLong3())
  50. areaAddr = self.getAreaAddr(offset + 8)
  51. else:
  52. countryAddr = self.getString(offset + 4)
  53. areaAddr = self.getAreaAddr()
  54. return countryAddr + " " + areaAddr
  55. def dump(self, first , last):
  56. if last > self.indexCount :
  57. last = self.indexCount
  58. for index in range(first, last):
  59. offset = self.firstIndex + index * 7
  60. self.ipdb.seek(offset)
  61. buf = self.ipdb.read(7)
  62. (ip, of1, of2) = struct.unpack("IHB", buf)
  63. address = self.getAddr(of1 + (of2 << 16))
  64. # 把GBK转为utf-8
  65. address = str(address, 'gbk').encode("utf-8")
  66. logger.info("%d %s %s" % (index, self.ip2str(ip), address))
  67. def setIpRange(self, index):
  68. offset = self.firstIndex + index * 7
  69. self.ipdb.seek(offset)
  70. buf = self.ipdb.read(7)
  71. (self.curStartIp, of1, of2) = struct.unpack("IHB", buf)
  72. self.curEndIpOffset = of1 + (of2 << 16)
  73. self.ipdb.seek(self.curEndIpOffset)
  74. buf = self.ipdb.read(4)
  75. (self.curEndIp,) = struct.unpack("I", buf)
  76. def getIpAddr(self, ip):
  77. L = 0
  78. R = self.indexCount - 1
  79. while L < R-1:
  80. M = int((L + R) / 2)
  81. self.setIpRange(M)
  82. if ip == self.curStartIp:
  83. L = M
  84. break
  85. if ip > self.curStartIp:
  86. L = M
  87. else:
  88. R = M
  89. self.setIpRange(L)
  90. # version information, 255.255.255.X, urgy but useful
  91. if ip & 0xffffff00 == 0xffffff00:
  92. self.setIpRange(R)
  93. if self.curStartIp <= ip <= self.curEndIp:
  94. address = self.getAddr(self.curEndIpOffset)
  95. # 把GBK转为utf-8
  96. address = str(address)
  97. else:
  98. address = "未找到该IP的地址"
  99. return address
  100. def getIpRange(self, ip):
  101. self.getIpAddr(ip)
  102. range = self.ip2str(self.curStartIp) + ' - ' \
  103. + self.ip2str(self.curEndIp)
  104. return range
  105. def getString(self, offset = 0):
  106. if offset :
  107. self.ipdb.seek(offset)
  108. str = b''
  109. ch = self.ipdb.read(1)
  110. (byte,) = struct.unpack('B', ch)
  111. while byte != 0:
  112. str += ch
  113. ch = self.ipdb.read(1)
  114. (byte,) = struct.unpack('B', ch)
  115. return str.decode('gbk')
  116. def ip2str(self, ip):
  117. return str(ip >> 24)+'.'+str((ip >> 16) & 0xff)+'.'+str((ip >> 8) & 0xff)+'.'+str(ip & 0xff)
  118. def str2ip(self, s):
  119. (ip,) = struct.unpack('I', socket.inet_aton(s))
  120. return ((ip >> 24) & 0xff) | ((ip & 0xff) << 24) | ((ip >> 8) & 0xff00) | ((ip & 0xff00) << 8)
  121. def getLong3(self, offset=0):
  122. if offset:
  123. self.ipdb.seek(offset)
  124. str = self.ipdb.read(3)
  125. (a, b) = struct.unpack('HB', str)
  126. return (b << 16) + a