-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathIP.cs
124 lines (113 loc) · 4.34 KB
/
IP.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using System;
using System.IO;
using System.Text;
namespace IP
{
class IP
{
private static void Main(string[] args)
{
IP.EnableFileWatch = true;
IP.Load("17monipdb.dat");
Console.WriteLine(string.Join("\n", IP.Find("8.8.8.8")));
Console.WriteLine(string.Join("\n", IP.Find("255.255.255.255")));
Console.ReadKey(true);
}
public static bool EnableFileWatch = false;
private static int offset;
private static uint[] index = new uint[256];
private static byte[] dataBuffer;
private static byte[] indexBuffer;
private static long lastModifyTime = 0L;
private static string ipFile;
private static readonly object @lock = new object();
public static void Load(string filename)
{
ipFile = new FileInfo(filename).FullName;
Load();
if (EnableFileWatch)
{
Watch();
}
}
public static string[] Find(string ip)
{
lock (@lock)
{
var ips = ip.Split('.');
var ip_prefix_value = int.Parse(ips[0]);
long ip2long_value = BytesToLong(byte.Parse(ips[0]), byte.Parse(ips[1]), byte.Parse(ips[2]),
byte.Parse(ips[3]));
var start = index[ip_prefix_value];
var max_comp_len = offset - 1028;
long index_offset = -1;
var index_length = -1;
byte b = 0;
for (start = start * 8 + 1024; start < max_comp_len; start += 8)
{
if (
BytesToLong(indexBuffer[start + 0], indexBuffer[start + 1], indexBuffer[start + 2],
indexBuffer[start + 3]) >= ip2long_value)
{
index_offset = BytesToLong(b, indexBuffer[start + 6], indexBuffer[start + 5],
indexBuffer[start + 4]);
index_length = 0xFF & indexBuffer[start + 7];
break;
}
}
var areaBytes = new byte[index_length];
Array.Copy(dataBuffer, offset + (int)index_offset - 1024, areaBytes, 0, index_length);
return Encoding.UTF8.GetString(areaBytes).Split('\t');
}
}
private static void Watch()
{
var file = new FileInfo(ipFile);
if (file.DirectoryName == null) return;
var watcher = new FileSystemWatcher(file.DirectoryName, file.Name) { NotifyFilter = NotifyFilters.LastWrite };
watcher.Changed += (s, e) =>
{
var time = File.GetLastWriteTime(ipFile).Ticks;
if (time > lastModifyTime)
{
Load();
}
};
watcher.EnableRaisingEvents = true;
}
private static void Load()
{
lock (@lock)
{
var file = new FileInfo(ipFile);
lastModifyTime = file.LastWriteTime.Ticks;
try
{
dataBuffer = new byte[file.Length];
using (var fin = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
{
fin.Read(dataBuffer, 0, dataBuffer.Length);
}
var indexLength = BytesToLong(dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3]);
indexBuffer = new byte[indexLength];
Array.Copy(dataBuffer, 4, indexBuffer, 0, indexLength);
offset = (int)indexLength;
for (var loop = 0; loop < 256; loop++)
{
index[loop] = BytesToLong(indexBuffer[loop * 4 + 3], indexBuffer[loop * 4 + 2],
indexBuffer[loop * 4 + 1],
indexBuffer[loop * 4]);
}
}
catch (Exception ex)
{
throw ex;
}
}
}
private static uint BytesToLong(byte a, byte b, byte c, byte d)
{
return ((uint)a << 24) | ((uint)b << 16) | ((uint)c << 8) | d;
}
}
}