refactor: 重构随机中国ip

This commit is contained in:
ElyPrism 2026-02-14 23:50:59 +08:00
parent b04b9d51fb
commit f08f192328
No known key found for this signature in database
3 changed files with 4201 additions and 77 deletions

View File

@ -1,26 +0,0 @@
开始IP,结束IP,IP个数,位置
1.0.1.0 ,1.0.3.255 ,768,福州
1.0.8.0 ,1.0.15.255 ,2048,广州
1.0.32.0 ,1.0.63.255 ,8192,广州
1.1.0.0 ,1.1.0.255 ,256,福州
1.1.2.0 ,1.1.63.255 ,15872,广州
1.2.0.0 ,1.2.2.255 ,768,北京
1.2.4.0 ,1.2.127.255 ,31744,广州
1.3.0.0 ,1.3.255.255 ,65536,广州
1.4.1.0 ,1.4.127.255 ,32512,广州
1.8.0.0 ,1.8.255.255 ,65536,北京
1.10.0.0 ,1.10.9.255 ,2560,福州
1.10.11.0 ,1.10.127.255 ,29952,广州
1.12.0.0 ,1.15.255.255 ,262144,上海
1.18.128.0 ,1.18.128.255 ,256,北京
1.24.0.0 ,1.31.255.255 ,524288,赤峰
1.45.0.0 ,1.45.255.255 ,65536,北京
1.48.0.0 ,1.51.255.255 ,262144,济南
1.56.0.0 ,1.63.255.255 ,524288,伊春
1.68.0.0 ,1.71.255.255 ,262144,忻州
1.80.0.0 ,1.95.255.255 ,1048576,北京
1.116.0.0 ,1.117.255.255 ,131072,上海
1.119.0.0 ,1.119.255.255 ,65536,北京
1.180.0.0 ,1.185.255.255 ,393216,桂林
1.188.0.0 ,1.199.255.255 ,786432,洛阳
1.202.0.0 ,1.207.255.255 ,393216,铜仁
1 开始IP 结束IP IP个数 位置
2 1.0.1.0 1.0.3.255 768 福州
3 1.0.8.0 1.0.15.255 2048 广州
4 1.0.32.0 1.0.63.255 8192 广州
5 1.1.0.0 1.1.0.255 256 福州
6 1.1.2.0 1.1.63.255 15872 广州
7 1.2.0.0 1.2.2.255 768 北京
8 1.2.4.0 1.2.127.255 31744 广州
9 1.3.0.0 1.3.255.255 65536 广州
10 1.4.1.0 1.4.127.255 32512 广州
11 1.8.0.0 1.8.255.255 65536 北京
12 1.10.0.0 1.10.9.255 2560 福州
13 1.10.11.0 1.10.127.255 29952 广州
14 1.12.0.0 1.15.255.255 262144 上海
15 1.18.128.0 1.18.128.255 256 北京
16 1.24.0.0 1.31.255.255 524288 赤峰
17 1.45.0.0 1.45.255.255 65536 北京
18 1.48.0.0 1.51.255.255 262144 济南
19 1.56.0.0 1.63.255.255 524288 伊春
20 1.68.0.0 1.71.255.255 262144 忻州
21 1.80.0.0 1.95.255.255 1048576 北京
22 1.116.0.0 1.117.255.255 131072 上海
23 1.119.0.0 1.119.255.255 65536 北京
24 1.180.0.0 1.185.255.255 393216 桂林
25 1.188.0.0 1.199.255.255 786432 洛阳
26 1.202.0.0 1.207.255.255 393216 铜仁

4147
data/china_ip_ranges.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +1,8 @@
const logger = require('./logger') const logger = require('./logger')
// 预先定义常量和函数引用 const fs = require('fs')
// 中国 IP 段来源data/ChineseIPGenerate.csv const path = require('path')
const chinaIPRangesRaw = [
// 开始IP, 结束IP, IP个数, 位置
['1.0.1.0', '1.0.3.255', 768, '福州'],
['1.0.8.0', '1.0.15.255', 2048, '广州'],
['1.0.32.0', '1.0.63.255', 8192, '广州'],
['1.1.0.0', '1.1.0.255', 256, '福州'],
['1.1.2.0', '1.1.63.255', 15872, '广州'],
['1.2.0.0', '1.2.2.255', 768, '北京'],
['1.2.4.0', '1.2.127.255', 31744, '广州'],
['1.3.0.0', '1.3.255.255', 65536, '广州'],
['1.4.1.0', '1.4.127.255', 32512, '广州'],
['1.8.0.0', '1.8.255.255', 65536, '北京'],
['1.10.0.0', '1.10.9.255', 2560, '福州'],
['1.10.11.0', '1.10.127.255', 29952, '广州'],
['1.12.0.0', '1.15.255.255', 262144, '上海'],
['1.18.128.0', '1.18.128.255', 256, '北京'],
['1.24.0.0', '1.31.255.255', 524288, '赤峰'],
['1.45.0.0', '1.45.255.255', 65536, '北京'],
['1.48.0.0', '1.51.255.255', 262144, '济南'],
['1.56.0.0', '1.63.255.255', 524288, '伊春'],
['1.68.0.0', '1.71.255.255', 262144, '忻州'],
['1.80.0.0', '1.95.255.255', 1048576, '北京'],
['1.116.0.0', '1.117.255.255', 131072, '上海'],
['1.119.0.0', '1.119.255.255', 65536, '北京'],
['1.180.0.0', '1.185.255.255', 393216, '桂林'],
['1.188.0.0', '1.199.255.255', 786432, '洛阳'],
['1.202.0.0', '1.207.255.255', 393216, '铜仁'],
]
// 将原始字符串段转换为数值段并计算总数(在模块初始化时完成一次) // IP地址转换函数
function ipToInt(ip) { function ipToInt(ip) {
const parts = ip.split('.').map(Number) const parts = ip.split('.').map(Number)
const a = (parts[0] << 24) >>> 0 const a = (parts[0] << 24) >>> 0
@ -49,20 +21,56 @@ function intToIp(int) {
].join('.') ].join('.')
} }
const chinaIPRanges = (function buildRanges() { // 解析CIDR格式的IP段
const arr = [] function parseCIDR(cidr) {
let total = 0 const [ipStr, prefixLengthStr] = cidr.split('/')
for (let i = 0; i < chinaIPRangesRaw.length; i++) { const prefixLength = parseInt(prefixLengthStr, 10)
const r = chinaIPRangesRaw[i]
const start = ipToInt(r[0]) const ipInt = ipToInt(ipStr)
const end = ipToInt(r[1]) const mask = (0xffffffff << (32 - prefixLength)) >>> 0
const count = r[2] || end - start + 1 const start = (ipInt & mask) >>> 0
arr.push({ start, end, count, location: r[3] || '' }) const end = (start | (~mask >>> 0)) >>> 0
total += count const count = end - start + 1
return { start, end, count, cidr }
}
// 从china_ip_ranges.txt加载中国IP段CIDR格式
const chinaIPRanges = (function loadChinaIPRanges() {
try {
const filePath = path.join(__dirname, '../data/china_ip_ranges.txt')
const content = fs.readFileSync(filePath, 'utf-8')
const lines = content
.split('\n')
.filter((line) => line.trim() && !line.startsWith('#'))
const arr = []
let total = 0
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim()
if (!line) continue
const range = parseCIDR(line)
arr.push(range)
total += range.count
}
// 按IP段大小排序提高随机选择效率
arr.sort((a, b) => b.count - a.count)
// attach total for convenience
arr.totalCount = total
logger.info(
`Loaded ${arr.length} Chinese IP ranges from china_ip_ranges.txt, total ${total} IPs`,
)
return arr
} catch (error) {
logger.error('Failed to load china_ip_ranges.txt:', error.message)
// 返回空数组generateRandomChineseIP会使用兜底逻辑
return { totalCount: 0 }
} }
// attach total for convenience
arr.totalCount = total
return arr
})() })()
const floor = Math.floor const floor = Math.floor
const random = Math.random const random = Math.random
@ -144,16 +152,11 @@ module.exports = {
// 如果没有选中(理论上不应该发生),回退到最后一个段 // 如果没有选中(理论上不应该发生),回退到最后一个段
if (!chosen) chosen = chinaIPRanges[chinaIPRanges.length - 1] if (!chosen) chosen = chinaIPRanges[chinaIPRanges.length - 1]
// 在段内随机生成一个 IP使用段真实的数值范围,而非 csv 中的 count // 在段内随机生成一个 IP使用段真实的数值范围
const segSize = chosen.end - chosen.start + 1 const segSize = chosen.end - chosen.start + 1
const ipInt = chosen.start + Math.floor(random() * segSize) const ipInt = chosen.start + Math.floor(random() * segSize)
const ip = intToIp(ipInt) const ip = intToIp(ipInt)
logger.info( logger.info('Generated Random Chinese IP:', ip, 'from CIDR:', chosen.cidr)
'Generated Random Chinese IP:',
ip,
'location:',
chosen.location,
)
return ip return ip
}, },
// 生成chainId的函数 // 生成chainId的函数