里德所罗门编码

云上做开发我们常常说要面向失败做设计,比如做Serverless应用的时候就常常需要在可能存在的丢包、并发写冲突、异常截断等情形下进行自我修复。

里德所罗门编码是一个典型的面试失败设计的编码,在这个时候就可以很方便的提供数据的冗余存储和自我修复能力

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
var rs = require('reedsolomon');
function RS(messageLength, errorCorrectionLength) {
var dataLength = messageLength - errorCorrectionLength;
var encoder = new rs.ReedSolomonEncoder(rs.GenericGF.AZTEC_DATA_8());
var decoder = new rs.ReedSolomonDecoder(rs.GenericGF.AZTEC_DATA_8());
return {
dataLength: dataLength,
messageLength: messageLength,
errorCorrectionLength: errorCorrectionLength,
encode : function (message) {
encoder.encode(message, errorCorrectionLength);
},
decode: function (message) {
decoder.decode(message, errorCorrectionLength);
}
};
}
let msg = "里德所罗门编码 https://www.npmjs.com/package/reedsolomon 真是一个神奇的编码方式";
let errorCorrectionLength=32;//冗余字节数
console.log("原始消息:",msg)
let dataLength=Buffer.from(msg).length;
var ec = RS(dataLength+errorCorrectionLength,errorCorrectionLength);
message=Buffer.alloc(ec.messageLength);
message.write(msg)
console.log('原始数据:',message.toString("hex"));
ec.encode(message);
console.log('编码数据:',message.toString("hex"));
//随机搞点破坏,只要破坏字节数量不超过冗余字节数的一半都没事
for (var i = 0; i < errorCorrectionLength/2; i++) message[ Math.floor(Math.random() * message.length) ] = 0;
console.log('搞点破坏:',message.toString("hex"));
try{
ec.decode(message);
bMsg = Buffer.alloc(dataLength);
for (var i = 0; i < ec.dataLength; i++) bMsg[i] = message[i];
console.log("修复数据:",bMsg.toString());
}catch(e){
console.log("------- 被破坏字节太多,修复不了 -------")
}

运行了一下,结果棒棒哒:

1
2
3
4
5
原始消息: 里德所罗门编码 https://www.npmjs.com/package/reedsolomon 真是一个神奇的编码方式
原始数据: e9878ce5beb7e68980e7bd97e997a8e7bc96e7a0812068747470733a2f2f7777772e6e706d6a732e636f6d2f7061636b6167652f72656564736f6c6f6d6f6e20e79c9fe698afe4b880e4b8aae7a59ee5a587e79a84e7bc96e7a081e696b9e5bc8f0000000000000000000000000000000000000000000000000000000000000000
编码数据: e9878ce5beb7e68980e7bd97e997a8e7bc96e7a0812068747470733a2f2f7777772e6e706d6a732e636f6d2f7061636b6167652f72656564736f6c6f6d6f6e20e79c9fe698afe4b880e4b8aae7a59ee5a587e79a84e7bc96e7a081e696b9e5bc8fd35925fe536e6969e8e38a5de682e29d1cdd997e3740235b690c1893ee4e9009
搞点破坏: e9878ce5beb7e68980e7bd97e900a8e7bc00e7a0812068747470733a2f007777772e6e706d6a7300636f6d2f7061636b6167652f72656564736f6c006d6f6e00009c9fe698afe4b800e4b8aae7a59ee5a587e79a84e7bc96e70081e696b9e5008fd35925fe536e6900e8e38a5de682e29d1c00007e3740235b690c1800ee4e9009
修复数据: 里德所罗门编码 https://www.npmjs.com/package/reedsolomon 真是一个神奇的编码方式