Chinaunix首页 | 论坛 | 博客
  • 博客访问: 286777
  • 博文数量: 60
  • 博客积分: 2697
  • 博客等级: 少校
  • 技术积分: 653
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-13 15:52
文章分类

全部博文(60)

文章存档

2012年(6)

2011年(31)

2010年(23)

分类: C/C++

2011-03-22 18:10:26

     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指针。

 

    下面这个例子实现了向一个文件写数据,并同时生成校验数据块,最后将原始数据和冗余数据一起保存。

  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include "fec.h"
  7. #define BUFSIZE (1024*4) //原始文件缓冲区大小
  8. #define FILESIZE (1024*1024*1024) //文件大小
  9. #define EC_K 4
  10. #define EC_M 8
  11. #define NR (EC_M - EC_K) //冗余块数量
  12. #define SZ (BUFSIZE/EC_K) //数据块大小
  13. int main(int argv, char *argc[])
  14. {
  15.         int fd,i=0,j=0,num;
  16.         unsigned blocks[NR];
  17.         fec_t *code;
  18.         char buf[BUFSIZE] = {0};
  19.         char dest[NR*SZ] = {0};
  20.         char *src[EC_K];
  21.         char *fecs[NR];
  22.         for(i = 0; i < EC_K; i++)
  23.              src[i] = buf + i*SZ;
  24.         for(i = 0; i < NR; i++){
  25.              blocks[i] = EC_K + i;
  26.              fecs[i] = dest + i*SZ;
  27.         }
  28.         num=FILESIZE/BUFSIZE;
  29.         code = fec_new(4, 6);
  30.         fd = open(filename,O_RDWR|O_APPEND|O_CREAT|O_SYNC);
  31.         if(fd < 0){
  32.              printf("file open failed!\n");
  33.              return -1;
  34.         }
  35.         while((j++) < num){
  36.              for(i = 0; i < BUFSIZE; i++)
  37.                   buf[i] = i%50 + '0';
  38.              fec_encode(code, (const gf*const*)src, (const gf*const*)fecs, blocks, NR, SZ);
  39.              ret = write(fd, buf, BUFSIZE);  //写入原始数据 
  40.              if(ret < 0)
  41.                  return -1;
  42.              ret = write(fd, dest, NR*SZ);   //写入冗余数据
  43.              if(ret < 0)
  44.                  return -1;
  45.         }
  46. /*以下代码是数据恢复过程,假设数据的第0,1块丢失或损坏
  47.         char *in_recovery[EC_K] = {fecs[0], fecs[1], buf+SZ*2, buf+SZ*3};
  48.         char buf_recovery[2*SZ];
  49.         char *out_recovery[2] = {buf_recovery, buf_recovery+SZ};
  50.         unsigned index[EC_K] = {4,5,2,3}; //对应in_recovery中数据块的索引
  51.         fec_decode(code, (const gf*const*)in_recovery, (const gf*const*)out_recovery, index, SZ);
  52. */
  53.         close(fd);
  54.         return 0;
  55. }
阅读(2433) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~