zfec是一种前向纠删码,用于给原始数据增加冗余信息,以提高数据的安全性。zfec为我们同时提供了C和Python接口。下面介绍一下zfec在c语言下的API 接口。
源代码下载地址:
在编写自己的程序之前,我们需要将zfec提供的fec.c编译成.o文件。如果在linux下编译时出现fec.h中的fec_encode()和fec_decode()无法编译通过,可以将形参中的restrict限定符去除。
1 fec_t* fec_new(unsigned k, unsigned m);
其中: k 原始数据包的分块数
m 编码后生成的总数据块(原始数据+编码数据)
显然m>k,块大小一致(fec_encode的sz就代表块大小),
2 void fec_encode(const fec_t* code, const gf*restrict const*restrict const src, gf*restrict const*restrict const fecs, const unsigned*restrict const block_nums, size_t num_block_nums, size_t sz);
其中: code 由fec_new()生成的fec_t结构,其中包含m,k和一个矩阵。
src 原始数据指针的一个数组,指针所指数组大小为k。
fecs 冗余数据的数组指针,不包含原始数据,所指数组大小为m-k。
block_nums 用来记录冗余数据块在整个数据(包含原始数据)中的索引的数组。
num_block_nums 冗余数组大小。
sz 每个数据块的大小。
举例,如果我们以(3,5)的方案来生成纠删码,则原始数据的索引是0-2,冗余数据的索引是4-5,那么block_nums数组的大小为5-3=2,即num_block_nums=2,其中block_nums[0]=3(第一个生成块的索引是3),block_num[1]=4,以此类推。
3 void fec_decode(const fec_t* code, const gf*restrict const*restrict const inpkts, gf*restrict const*restrict const outpkts, const unsigned*restrict const index, size_t sz);
其中: inpkts 用来恢复丢失数据的数据数组,其内的指针必须按编码前的顺序升序存放,如果丢包则拿 冗余块补入,其中冗余块必须放在丢失数据块的位置。指针所指数组大小为k。
outpkts 存放找回的数据块,所指数组大小为丢失块数量。
index 传入的数据包的序号,数组大小为k,对应inpkts中每个数据块在全部数据块中的索引。
举例,还是采用(3,5)编码,其中索引为2的原始数据块丢失,那么我们将随意寻找一个冗余数据块m(3<=m<=4),那么,index[] = {0,1,m,2};同样,在inpkts中,数据块m的指针应放在第3位。
4 void fec_free(fec_t* p);
释放fec_t指针。
下面这个例子实现了向一个文件写数据,并同时生成校验数据块,最后将原始数据和冗余数据一起保存。
- #include
- #include
- #include
- #include
- #include
- #include "fec.h"
- #define BUFSIZE (1024*4) //原始文件缓冲区大小
- #define FILESIZE (1024*1024*1024) //文件大小
- #define EC_K 4
- #define EC_M 8
- #define NR (EC_M - EC_K) //冗余块数量
- #define SZ (BUFSIZE/EC_K) //数据块大小
- int main(int argv, char *argc[])
- {
- int fd,i=0,j=0,num;
- unsigned blocks[NR];
- fec_t *code;
- char buf[BUFSIZE] = {0};
- char dest[NR*SZ] = {0};
- char *src[EC_K];
- char *fecs[NR];
- for(i = 0; i < EC_K; i++)
- src[i] = buf + i*SZ;
- for(i = 0; i < NR; i++){
- blocks[i] = EC_K + i;
- fecs[i] = dest + i*SZ;
- }
- num=FILESIZE/BUFSIZE;
- code = fec_new(4, 6);
- fd = open(filename,O_RDWR|O_APPEND|O_CREAT|O_SYNC);
- if(fd < 0){
- printf("file open failed!\n");
- return -1;
- }
- while((j++) < num){
- for(i = 0; i < BUFSIZE; i++)
- buf[i] = i%50 + '0';
- fec_encode(code, (const gf*const*)src, (const gf*const*)fecs, blocks, NR, SZ);
- ret = write(fd, buf, BUFSIZE); //写入原始数据
- if(ret < 0)
- return -1;
- ret = write(fd, dest, NR*SZ); //写入冗余数据
- if(ret < 0)
- return -1;
- }
- /*以下代码是数据恢复过程,假设数据的第0,1块丢失或损坏
- char *in_recovery[EC_K] = {fecs[0], fecs[1], buf+SZ*2, buf+SZ*3};
- char buf_recovery[2*SZ];
- char *out_recovery[2] = {buf_recovery, buf_recovery+SZ};
- unsigned index[EC_K] = {4,5,2,3}; //对应in_recovery中数据块的索引
- fec_decode(code, (const gf*const*)in_recovery, (const gf*const*)out_recovery, index, SZ);
- */
- close(fd);
- return 0;
- }
阅读(2489) | 评论(0) | 转发(0) |