using System;
using System.IO;
using Microsoft.VisualBasic;
namespace Test
{
internal class QQCry
{
private FileStream fs = null;
private BinaryReader r = null;
private uint sip, eip, qqwryendpos;
// 获取数据库记录总数
public uint GetQQWryRecord()
{
uint startpos = 0, endpos = 0;
if (r != null)
{
r.BaseStream.Seek(0, SeekOrigin.Begin);
startpos = r.ReadUInt32();
endpos = r.ReadUInt32();
startpos = (endpos - startpos) / 7 + 1;
}
qqwryendpos = endpos;
return startpos;
}
// 获取IP记录号
private uint FindIPPos(uint ip)
{
uint count = GetQQWryRecord();
uint s = 0, e = count - 1, m = 0;
while (s <= e)
{
m = (s + e) / 2;
GetQQWryIPDataArea(m);
if (sip <= ip && ip <= eip) return m;
else if (sip > ip) e = m - 1;
else if (eip < ip) s = m + 1;
}
return 0;
}
// 获取字符串长度
private uint GetQQWryStringLength(string str)
{
uint len = 0;
int i;
for (i = 0; i < str.Length; i++)
{
if (str[i] > 127) len += 2;
else len++;
}
return len;
}
// 获取IP范围
private void GetQQWryIPDataArea(uint tell)
{
uint pos;
r.BaseStream.Seek(0, SeekOrigin.Begin);
pos = r.ReadUInt32() + tell * 7;
r.BaseStream.Seek(pos, SeekOrigin.Begin);
sip = r.ReadUInt32();
if (pos >= qqwryendpos - 7)
{
pos = Convert.ToUInt32(r.ReadByte());
pos += Convert.ToUInt32(r.ReadByte()) * 256;
pos += Convert.ToUInt32(r.ReadByte()) * 256 * 256;
}
else
{
pos = r.ReadUInt32() & 0x00FFFFFF;
}
r.BaseStream.Seek(pos, SeekOrigin.Begin);
eip = r.ReadUInt32();
}
// 获取字符串
private string GetQQWryDataString(uint tell)
{
uint pos;
byte ch;
string str1, str2 = "";
r.BaseStream.Seek(0, SeekOrigin.Begin);
pos = r.ReadUInt32() + tell * 7;
r.BaseStream.Seek(pos, SeekOrigin.Begin);
sip = r.ReadUInt32();
if (pos >= qqwryendpos - 7)
{
pos = Convert.ToUInt32(r.ReadByte());
pos += Convert.ToUInt32(r.ReadByte()) * 256;
pos += Convert.ToUInt32(r.ReadByte()) * 256 * 256;
}
else
{
pos = r.ReadUInt32() & 0x00FFFFFF;
}
r.BaseStream.Seek(pos, SeekOrigin.Begin);
eip = r.ReadUInt32();
pos += 4;
ch = r.ReadByte();
if (ch == 1)
{
pos = r.ReadUInt32() & 0x00FFFFFF;
r.BaseStream.Seek(pos, SeekOrigin.Begin);
ch = r.ReadByte();
}
if (ch == 2)
{
r.BaseStream.Seek(pos + 1, SeekOrigin.Begin);
str1 = GetQQWryFileString(r.ReadUInt32() & 0x00FFFFFF);
pos += 4;
}
else
{
str1 = GetQQWryFileString(pos);
pos += GetQQWryStringLength(str1) + 1;
}
r.BaseStream.Seek(pos, SeekOrigin.Begin);
ch = r.ReadByte();
if (ch == 2) pos = r.ReadUInt32() & 0x00FFFFFF;
str2 = GetQQWryFileString(pos);
return str1 + " " + str2;
}
// 从二进制文件读取字符串
private string GetQQWryFileString(uint tell)
{
string str = "";
byte val = 1;
byte[] buff = new byte[2];
r.BaseStream.Seek(tell, SeekOrigin.Begin);
while (val != 0)
{
val = r.ReadByte();
if (val == 0) break;
if (val > 127)
{
buff[0] = val;
buff[1] = r.ReadByte();
str += System.Text.Encoding.GetEncoding("GB2312").GetString(buff);
}
else str += Convert.ToChar(val);
}
return str;
}
// 地址转换为IP
public uint GetQQWryAddrToIP(string addr)
{
uint i;
uint[] ip = new uint[4];
string[] strs = addr.Split('.');
ip[0] = 255;
ip[1] = 255;
ip[2] = 255;
ip[3] = 255;
for (i = 0; i < strs.Length && i < 4; i++)
{
try
{
ip[i] = Convert.ToUInt32(strs[i]);
}
catch
{
ip[i] = 255;
}
if (ip[i] < 0) ip[i] = 0;
else if (ip[i] > 255) ip[i] = 255;
}
return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
}
// IP转换为地址
public string GetQQWryIPToAddr(uint ip)
{
string str;
str = Convert.ToString((ip >> 24) & 0xFF);
str += ".";
str += Convert.ToString((ip >> 16) & 0xFF);
str += ".";
str += Convert.ToString((ip >> 8) & 0xFF);
str += ".";
str += Convert.ToString(ip & 0xFF);
return str;
}
// 从IP地址获取字符串
public string GetQQWryString(string addr)
{
string str = "";
try
{
fs = new FileStream("qqway.dat", FileMode.Open, FileAccess.Read);
if (fs != null) r = new BinaryReader(fs);
str = GetQQWryDataString(FindIPPos(GetQQWryAddrToIP(addr)));
r.Close();
fs.Close();
}
catch { }
return str;
}
// 繁简转换
static public string ToBig5(string str)
{
return Strings.StrConv(str, VbStrConv.TraditionalChinese, 0);
}
static public string ToBG2312(string str)
{
return Strings.StrConv(str, VbStrConv.SimplifiedChinese, 0);
}
}
}
function GF_ConvertIP($ip){
if($fd = @fopen('qqwry.dat', 'rb')){
$ip = explode('.', $ip);
$ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];
$DataBegin = fread($fd, 4);
$DataEnd = fread($fd, 4);
$ipbegin = implode('', unpack('L', $DataBegin));
if($ipbegin < 0) $ipbegin += pow(2, 32);
$ipend = implode('', unpack('L', $DataEnd));
if($ipend < 0) $ipend += pow(2, 32);
$ipAllNum = ($ipend - $ipbegin) / 7 + 1;
$BeginNum = 0;
$EndNum = $ipAllNum;
$ip1num = 0 ; $ip2num = 0;
$ipAddr1 = ''; $ipAddr2 = '';
while($ip1num > $ipNum || $ip2num < $ipNum) {
$Middle= intval(($EndNum + $BeginNum) / 2);
fseek($fd, $ipbegin + 7 * $Middle);
$ipData1 = fread($fd, 4);
if(strlen($ipData1) < 4) { fclose($fd); return ''; }
$ip1num = implode('', unpack('L', $ipData1));
if($ip1num < 0) $ip1num += pow(2, 32);
if($ip1num > $ipNum) {
$EndNum = $Middle;
continue;
}
$DataSeek = fread($fd, 3);
if(strlen($DataSeek) < 3) { fclose($fd); return ''; }
$DataSeek = implode('', unpack('L', $DataSeek.chr(0)));
fseek($fd, $DataSeek);
$ipData2 = fread($fd, 4);
if(strlen($ipData2) < 4) { fclose($fd); return ''; }
$ip2num = implode('', unpack('L', $ipData2));
if($ip2num < 0) $ip2num += pow(2, 32);
if($ip2num < $ipNum) {
if($Middle == $BeginNum) { fclose($fd); return ''; }
$BeginNum = $Middle;
}
}
$ipFlag = fread($fd, 1);
if($ipFlag == chr(1)) {
$ipSeek = fread($fd, 3);
if(strlen($ipSeek) < 3) { fclose($fd); return ''; }
$ipSeek = implode('', unpack('L', $ipSeek.chr(0)));
fseek($fd, $ipSeek);
$ipFlag = fread($fd, 1);
}
if($ipFlag == chr(2)) {
$AddrSeek = fread($fd, 3);
if(strlen($AddrSeek) < 3) { fclose($fd); return ''; }
$ipFlag = fread($fd, 1);
if($ipFlag == chr(2)) {
$AddrSeek2 = fread($fd, 3);
if(strlen($AddrSeek2) < 3) { fclose($fd); return ''; }
$AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
fseek($fd, $AddrSeek2);
} else {
fseek($fd, -1, SEEK_CUR);
}
while(($char = fread($fd, 1)) != chr(0)) $ipAddr2 .= $char;
$AddrSeek = implode('', unpack('L', $AddrSeek.chr(0)));
fseek($fd, $AddrSeek);
while(($char = fread($fd, 1)) != chr(0)) $ipAddr1 .= $char;
} else {
fseek($fd, -1, SEEK_CUR);
while(($char = fread($fd, 1)) != chr(0)) $ipAddr1 .= $char;
$ipFlag = fread($fd, 1);
if($ipFlag == chr(2)) {
$AddrSeek2 = fread($fd, 3);
if(strlen($AddrSeek2) < 3) { fclose($fd); return ''; }
$AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
fseek($fd, $AddrSeek2);
} else {
fseek($fd, -1, SEEK_CUR);
}
while(($char = fread($fd, 1)) != chr(0)) $ipAddr2 .= $char;
}
fclose($fd);
return "{$ipAddr1} {$ipAddr2}";
}
return '';
}
用法参考:
纯真IP库QQWry.dat文件解析 - 知乎 (zhihu.com)
C:\Users\Raise\AppData\Local\VirtualStore\Program Files (x86)\cz88.net\ip\qqwry.dat