这样做的好处是什么?举个例子,上面提到哈希函数常用于加密密码,如果黑客拿到了这些密码哈希值,虽然他们不能根据哈希值倒推出密码,但由于哈希函数有一个特性,相同的输入总会产生相同的输出,黑客只需要找一些常用的密码,对它们进行哈希处理(rainbow table),然后再与数据库中的哈希密码值比较,还是有很大可能会得到一些密码的。
DOS(Denial Of Service) 攻击是指攻击者发起大量请求,把服务器的资源耗尽,使得服务器无法响应正常用户的请求。
hashable value must be immutable value.
/**
* 一个简单的哈希函数,返回字符串前三位 ASCII 码的和
* @param {string} str
*/
function hash(str) {
return [].reduce.call(
str.slice(0, 3),
(res, s) => res + s.charCodeAt(0),
0,
);
}
class HashTable {
constructor(elements) {
this.buketSize = elements.length;
this.bukets = Array(this.buketSize)
.fill(null)
.map(() => []);
for (const [k, v] of elements) {
this.put(k, v);
}
}
_getBuket(key) {
const index = hash(key) % this.buketSize;
return this.bukets[index];
}
put(key, value) {
const buket = this._getBuket(key);
for (const kv of buket) {
if (kv[0] === key) {
kv[1] = value;
return;
}
}
buket.push([key, value]);
}
get(key) {
const buket = this._getBuket(key);
for (const [k, v] of buket) {
if (k === key) return v;
}
}
}
const elements = [
['France', 'Paris'],
['United States', 'Washington D.C.'],
['Italy', 'Rome'],
['Canada', 'Ottawa'],
];
const hashtable = new HashTable(elements);
console.log(hashtable.get('Italy')); // Rome
hashtable.put('Canada', 'yoyo');
console.log(hashtable.bukets);
// [
// [['United States', 'Washington D.C.']],
// [['France', 'Paris']],
// [
// ['Italy', 'Rome'],
// ['Canada', 'yoyo'],
// ],
// [],
// ];
/**
* 一个简单的哈希函数,返回字符串前三位 ASCII 码的和
* @param {string} str
*/
function hash(str) {
return [].reduce.call(
str.slice(0, 3),
(res, s) => res + s.charCodeAt(0),
0,
);
}
class HashTable {
constructor(elements) {
this.buketSize = elements.length;
this.bukets = Array(this.buketSize).fill(null);
for (const [k, v] of elements) {
this.put(k, v);
}
}
put(key, value) {
const start = hash(key) % this.buketSize;
let index = start;
while (this.bukets[index] !== null) {
// 已存在的 key,覆盖
if (this.bukets[index][0] === key) break;
index = (index + 1) % this.buketSize;
// bukets 已经满了,扩展空间
if (index === start) {
this.bukets.push([key, value]);
this.buketSize++;
return;
}
}
this.bukets[index] = [key, value];
}
get(key) {
const start = hash(key) % this.buketSize;
let index = start;
while (this.bukets[index][0] !== key) {
index = (index + 1) % this.buketSize;
// key 不存在
if (index === start) return;
}
return this.bukets[index][1];
}
}