ZX IPv6地址数据库之C#解析


一、ZX IPv6地址数据库是什么

首页 | 查询接口 | IPv6地址分配概览

二、数据库格式解析

文件格式详解

每行16字节(128bit)

0123 4567 89ab cdef 0123 4567 89ab cdef # 列标号 0-15字节
---- ---- ---- ---- ---- ---- ---- ----
4950 4442 0100 0308 4d28 0200 0000 0000 # `4950 4442`为`IPDB`;`0100`版本号2; 03 偏移地址长度
                                        # `08`IP地址长度 `4d28 0200`记录数 77+40*256+2*256*256=141389
cfb2 0800 0000 0000 0000 0000 0000 0000 # `cfb2 0800 0000 0000`索引区第一条记录的偏移207+178*256+8*256*256=570063
2800 0000 0000 0000 3230 3230 3035 3036 # `2800 0000 0000 0000`数据库版本字符串的偏移`40字节`
                                        # `3230 3230`开始之后就是正式的数据了
0049 414e 41e4 bf9d e795 99e5 9cb0 e59d
8000 0049 414e 41e7 89b9 e6ae 8ae5 9cb0
e59d 8000 e58c 85e5 90ab 7634 e59c b0e5
9d80 e79a 8476 36e5 9cb0 e59d 8000 0243
0000 e4bb 85e7 94a8 e4ba 8ee4 b8a2 e5bc
83e7 9a84 e59c b0e5 9d80 0002 4300 00e6
9caa e79f a5e5 9cb0 e59d 8000 0243 0000

# 以下是特殊的解码方法
928c e4b8 ade5 9bbd e6b2 b3e5 8c97 e79c # `e4b8 ade5 9bbd`中国;`e6b2 b3e5 8c97`河北
----
0638 030e 24d2 0c08 0000 0008 3803 0e24 # `0000 0008 3803 0e24` 240e:0338:0800:0000
da0c 0800 0000 0a38 030e 24e2 0c08 0000 # `da 0c08` 地址索引218+12*256+8*256*256=527578
0638 030e 24d2 0c08 0000 0008 3803 0e24
文件头
0~3	字符串	"IPDB"
4-5	short	版本号,现在是2。版本号0x01到0xFF之间保证互相兼容。
6	byte	偏移地址长度(2~8)
7	byte	IP地址长度(4或8或12或16, 现在只支持4(ipv4)和8(ipv6))
8~15	int64	记录数
16-23	int64	索引区第一条记录的偏移
24	byte	地址字段数(1~255)[版本咕咕咕新增,现阶段默认为2]
25-31	reserve	保留,用00填充
32~39	int64	数据库版本字符串的偏移[版本2新增,版本1没有]

该二进制文件的结构为

文件读取流程详解

例如:

三、文件读写

读文件

string dbFile = "[文件路径]";
FileStream stream = new FileStream(dbFile, FileMode.OpenOrCreate, FileAccess.ReadWrite);
stream.Seek(v, SeekOrigin.Begin); //偏移字节数(修改文件指针)
stream.Read(bytes, 0, bytes.Length); //读取字节并写入到bytes中
stream.Flush();
stream.Close();
stream = null;
return bytes;

写文件

string dbFile = "[文件路径]";
FileStream stream = new FileStream(dbFile, FileMode.OpenOrCreate, FileAccess.ReadWrite);
stream.Write(bytes, 0, bytes.Length);
Console.WriteLine("文件指针:"+stream.Position);
stream.Flush();
stream.Close();
stream = null;

[文件路径]的文件内容将会变成写入的内容

四、C#解析

(1)从文件中读取任意字节

/// <summary>
/// 读数据:size字节
/// </summary>
/// <param name="seek">位置偏移量</param>
/// <param name="size">需要数据长度</param>
/// <returns>byte[]</returns>
public byte[] read(int seek,int size = 8)
{
    if (seek0 > 0)
    {
        this.seek(seek);
    }
    var bytes = new byte[size];
    stream.Read(bytes, 0, bytes.Length);
    return bytes;
}

(2)从文件中读取自定义字节并转换成数字

/// <summary>
/// 读数据:3字节的数字
/// </summary>
/// <param name="seek">位置偏移量</param>
/// <param name="size">需要数据长度</param>
/// <returns></returns>
public int read3(int seek, int size = 3)
{
    if (seek > 0)
    {
        this.seek(seek);
    }
    var bytes = new byte[size];
    stream.Read(bytes, 0, bytes.Length);
    return bytes[0] + bytes[1] * 256 + bytes[2] * 256 * 256;
}

五、生成EXE查询工具

IPv6查询工具

下载

IPv6查询工具

总结:

(1)按字节读取数据

(2)字节数据转换成数字,是从左到右

例如:804020 转换过程为 80 + 40 * 256 + 20 * 256 * 256

参考资料

狮子的魂/ip2region(C#解析二进制文件)