/
ip.js
executable file
·91 lines (69 loc) · 1.94 KB
/
ip.js
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
'use strict';
var net = require('net');
var parseIPv4 = function(ip) {
ip = ip.split('.', 4);
var o0 = parseInt(ip[0]),
o1 = parseInt(ip[1]),
o2 = parseInt(ip[2]),
o3 = parseInt(ip[3]);
return [o0, o1, o2, o3];
};
var parseIPv6 = function(ip) {
var addr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
var i;
var parsed;
var chunk;
var hex = function(v) {
v = parseInt(v, 10).toString(16);
return (v.length == 2) ? v : '0' + v;
};
// ipv4 e.g. `::ffff:64.17.254.216`
if (ip.indexOf('.') > -1) {
ip = ip.replace(/(\d+)\.(\d+)\.(\d+)\.(\d+)/, function(match, a, b, c, d) {
return hex(a) + hex(b) + ':' + hex(c) + hex(d);
});
}
var parts = ip.split('::', 2),
left = parts[0],
right = parts[1];
if (left) {
parsed = left.split(':');
for (i = 0; i < parsed.length; i++) {
chunk = parseInt(parsed[i], 16);
addr[i * 2] = chunk >> 8;
addr[i * 2 + 1] = chunk & 0xff;
}
}
if (right) {
parsed = right.split(':');
var offset = 16 - (parsed.length * 2); // 2 bytes per chunk
for (i = 0; i < parsed.length; i++) {
chunk = parseInt(parsed[i], 16);
addr[offset + (i * 2)] = chunk >> 8;
addr[offset + (i * 2 + 1)] = chunk & 0xff;
}
}
return addr;
};
exports.parse = function(ip) {
return (ip.indexOf(':') === -1) ? parseIPv4(ip) : parseIPv6(ip);
};
exports.bitAt = function(rawAddress, idx) {
// 8 bits per octet in the buffer (>>3 is slightly faster than Math.floor(idx/8))
var bufIdx = idx >> 3;
// Offset within the octet (basicallg equivalent to 8 - (idx % 8))
var bitIdx = 7 ^ (idx & 7);
// Shift the offset rightwards by bitIdx bits and & it to grab the bit
return (rawAddress[bufIdx] >>> bitIdx) & 1;
};
exports.validate = function(ip) {
var version = net.isIP(ip);
switch (version) {
case 4:
return net.isIPv4(ip);
case 6:
return net.isIPv6(ip);
default:
return false;
}
};