rats-search/lib/table.js
2016-12-31 06:32:56 +03:00

72 lines
1.4 KiB
JavaScript

'use strict'
const crypto = require('crypto')
class Node {
static generateID() {
return crypto.createHash('sha1').update(crypto.randomBytes(20)).digest()
}
constructor(id) {
this.id = id || Node.generateNodeID()
}
static neighbor(target, id) {
return Buffer.concat([target.slice(0, 10), id.slice(10)])
}
static encodeNodes(nodes) {
return Buffer.concat(nodes.map((node)=> Buffer.concat([node.id, Node.encodeIP(node.address), Node.encodePort(node.port)])))
}
static decodeNodes(data) {
const nodes = []
for (let i = 0; i + 26 <= data.length; i += 26) {
nodes.push({
id: data.slice(i, i + 20),
address: `${data[i + 20]}.${data[i + 21]}.${data[i + 22]}.${data[i + 23]}`,
port: data.readUInt16BE(i + 24)
})
}
return nodes
}
static encodeIP(ip) {
return Buffer.from(ip.split('.').map((i)=>parseInt(i)))
}
static encodePort(port) {
const data = Buffer.alloc(2)
data.writeUInt16BE(port, 0)
return data
}
}
class Table{
constructor(cap) {
this.id = Node.generateID()
this.nodes = []
this.caption = cap
}
add(node) {
if (this.nodes.length < this.caption) {
this.nodes.push(node)
}
}
shift() {
return this.nodes.shift()
}
size() {
return this.nodes.length;
}
first() {
if(this.nodes.length >= 8) {
return this.nodes.slice(0, 8)
}else if(this.nodes.length > 0) {
return new Array(8).join().split(',').map(()=> this.nodes[0])
}
return []
}
}
module.exports = {Table, Node}