第十章   文本数据库

10.1  概述

Openss实现了一个简单的文本数据库,它可以从文件读取数据和将数据写到文件中,并且可以根据关键字段来查询数据。Openssl的文本数据库供apps/目录下的文件调用,比如apps.c、ca.c和ocsp.c。openssl文本数据库典型的例子为apps/demoCA/index.txt。文本数据库一行代表数据库的一行,各个列之间必须用一个\t隔开,用#进行注释(#必须在开始位置),以空行结束。比如下面的例子:

赵春平    28    湖北

zcp  28    荆门

文本数据库的查找用到了哈希表。openssl读取的所有行数据存放在堆栈中,并为每一列数据建立一个单独的哈希表。每个哈希表中存放了所有行数据的地址。查询时,用户指定某一列,openssl根据对应的哈希表进行查找。

10.2  数据结构

数据结构在crypto/txt_db/txt_db.h中定义,如下:

typedef struct txt_db_st

{

int num_fields;

STACK *data;

LHASH **index;

int (**qual)(char **);

long error;

long arg1;

long arg2;

char **arg_row;

} TXT_DB;

意义如下:

num_fields:表明文本数据库的列数。

data:用来存放数据,每一行数据组织成为一个字符串数组(每个数组值对应该行的一列),  并将此数组地址push到堆栈中。

index:哈希表数组,每一列对应一个哈希表。每一列都可以建哈希表,如果不建哈希表将不能查找该列数据。

qual:一个函数地址数组,数组的每个元素对应一列,进行插入该列哈希表前的过滤。这些函数用于判断一行数据的一列或者多列是否满足某种条件,如果满足将不能插入到哈希表中去(但是能存入堆栈)。每一列都可以设置一个这样的函数。这些函数由用户实现。比如,一个文本数据库中,有名字列和年龄列,并且要求名字长度不能小于2,年龄不能小于0和大于200。用户为名字列实现了一个qual函数,只用来检查名字长度,对于年龄列实现一个qual函数,只用来检查年龄。当用户要插入一条记录,名字长度为1,但是年龄合法,那么该记录能插入到年龄列对应的哈希表中,而不能插入名字列对应的哈希表。

error、arg1、arg2和arg_row用于存放错误信息。

10.3  函数说明

1)  TXT_DB *TXT_DB_read(BIO *in, int num)

用于从BIO中读入数据,转换为TXT_DB,num用于明确指明列数,本函数不建立哈希表。

2)  long TXT_DB_write(BIO *out, TXT_DB *db)

将TXT_DB内容写入BIO;

3)  int TXT_DB_create_index(TXT_DB *db,int field,int (*qual)(char **),

LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)

给field指定的列建立哈希表。db为需要建索引的TXT_DB,hash为一行数据的hash运算回调函数,cmp为一行数据的比较函数。

4)  char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value)

根据关键字段来查询数据,查询结果返回一行数据db为文本数据库,idx表明采用哪一列的哈希表来查找;value为查询条件。

5)  int TXT_DB_insert(TXT_DB *db,char **value)

往TXT_DB中插入一行数据。value数组以NULL表示结束。

6)    void TXT_DB_free(TXT_DB *db)

清除TXT_DB。

10.4  编程示例

/* txtdb.dat的内容

赵春平    28    湖北       无

zcp  28    荆门       无

*/

#include <openssl/bio.h>

#include <openssl/txt_db.h>

#include <openssl/lhash.h>

/* 名字过滤 */

static       int    name_filter(char **in)

{

if(strlen(in[0])<2)

return 0;

return 1;

}

static unsigned long index_name_hash(const char **a)

{

const char *n;

n=a[0];

while (*n == '0') n++;

return(lh_strhash(n));

}

static int index_name_cmp(const char **a, const char **b)

{

const char *aa,*bb;

for (aa=a[0]; *aa == '0'; aa++);

for (bb=b[0]; *bb == '0'; bb++);

return(strcmp(aa,bb));

}

int    main()

{

TXT_DB        *db=NULL,*out=NULL;

BIO               *in;

int                  num,ret;

char        **added=NULL,**rrow=0,**row=NULL;

in=BIO_new_file("txtdb.dat","r");

num=1024;

db=TXT_DB_read(in,4);

added=(char **)OPENSSL_malloc(sizeof(char *)*(3+1));

added[0]=(char *)OPENSSL_malloc(10);

#if 1

strcpy(added[0],"skp");

#else

strcpy(added[0],"a");     /* 不能插入名字对应的哈希表 */

#endif

added[1]=(char *)OPENSSL_malloc(10);

strcpy(added[1],"22");

added[2]=(char *)OPENSSL_malloc(10);

strcpy(added[2],"chairman");

added[3]=NULL;

ret=TXT_DB_insert(db,added);

if(ret!=1)

{

printf("err!\n");

return -1;

}

ret=TXT_DB_create_index(db,0, name_filter,index_name_hash,index_name_cmp);

if(ret!=1)

{

printf("err\n");

return 0;

}

row=(char **)malloc(2*sizeof(char *));

row[0]=(char *)malloc(10);

strcpy(row[0],"skp");

row[1]=NULL;

rrow=TXT_DB_get_by_index(db,0,row);

if(rrow!=NULL)

printf("%s      %s   %s\n",rrow[0],rrow[1],rrow[2]);

out=BIO_new_file("txtdb2.dat","w");

ret=TXT_DB_write(out,db);

TXT_DB_free(db);

BIO_free(in);

BIO_free(out);

return 0;

}

本示例只对第一列做了哈希。需要注意的是,added数组及其元素申请空间时尽量采用OPENSSL_malloc而不是malloc,且其申请的空间由TXT_DB_free(调用OPENSSL_free)释放。

《openssl 编程》之文本数据库相关推荐

  1. openssl 编程。 证书制作

    首页 博客 学院 下载 GitChat TinyMind 论坛 问答 商城 VIP 活动 写博客 发Chat 登录注册 么刚的专栏 RSS订阅 原 openssl证书制作及编程 2010年07月29日 ...

  2. 《openssl 编程》之 RSA(转)

    17.1  RSA介绍 RSA算法是一个广泛使用的公钥算法.其密钥包括公钥和私钥.它能用于数字签名.身份认证以及密钥交换.RSA密钥长度一般使用1024位或者更高.RSA密钥信息主要包括[1]: Ø  ...

  3. 《openssl 编程》之 DH

    第十九章DH 19.1  DH算法介绍 DH算法是W.Diffie和M.Hellman提出的.此算法是最早的公钥算法.它实质是一个通信双方进行密钥协商的协议:两个实体中的任何一个使用自己的私钥和另一实 ...

  4. 《openssl 编程》之错误处理

    第十四章   错误处理 14.1  概述 程序设计时,一般通过函数的返回值来判断是否调用成功.设计良好的函数以及好的错误处理能帮助调用者快速找到错误原因.错误处理应该尽可能多的包含各种信息,包括: Ø ...

  5. 《openssl 编程》之数据压缩

    16.1 简介 数据压缩是将原有数据通过某种压缩算法计算得到相对数据量小的过程.这种过程是可逆的,即能通过压缩后的数据恢复出原数据.数据压缩能够节省存储空间,减轻网络负载. 在即需要加密又需要压缩的情 ...

  6. 《openssl编程》之配置文件

    第八章 配置文件 8.1 概述 Openssl采用自定义的配置文件来获取配置信息.Openssl的配置文件主要由如下内容组成: 注释信息,注释信息由#开头: 段信息,段信息由[xxx]来表示,其中xx ...

  7. 《openssl编程》之BIO

    第七章   抽象IO 7.1    openssl抽象IO openssl抽象IO(I/O abstraction,即BIO)是openssl对于io类型的抽象封装,包括:内存.文件.日志.标准输入输 ...

  8. OPENSSL编程 第二十章 椭圆曲线

    20.1  ECC介绍 椭圆曲线算法可以看作是定义在特殊集合下数的运算,满足一定的规则.椭圆曲线在如下两个域中定义:Fp域和F2m域. Fp域,素数域,p为素数: F2m域:特征为2的有限域,称之为二 ...

  9. 笔记整理——使用openssl编程

    error: openssl 的所有解决方案 (2013/6/22 17:39:00) error: openssl/crypto.h: No such file or directory 解决方案 ...

最新文章

  1. php ajax 概率 转盘,php+jquery实现转盘抽奖 概率可任意调
  2. Science | 智能计算揭示前生命化学网络中合成的连接、出现和自我再生
  3. R语言使用table函数计算单分类变量的频率表(frequency table)、使用prop.table函数将table函数计算获得的频率表转化为比率表、返回单分类变量每一个类别的比率、或者百分比
  4. mysql自定义收藏分类_MYSQL中SHOW的使用整理收藏
  5. xshell连接服务器失败_xshell-ssh连接服务器被经常意外中断
  6. InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor
  7. asp.net C# 时间格式大全
  8. linux whois rpm,CentOS系统安装whois命令的方法
  9. 如何销毁一个实例化对象_JAVA中如何创建和销毁对象
  10. pls-toolbox_使用T-SQL Toolbox数据库解决时区,GMT和UTC问题
  11. 任何时候都不要轻易满仓
  12. Lync Server 2013 标准版部署(十)边缘服务器部署[三]
  13. 打包contrail-setup
  14. macbookpro2011安装单系统win10
  15. Spring Security 官方文档学习路径
  16. windows 连接蓝牙耳机失败 解决方法
  17. 物理机安装 CentOS 8.3
  18. 每日写题分享--优先队列
  19. HTML实现简单的注册页面
  20. Word排版小技巧 | 快速论文排版

热门文章

  1. BufferedOutputStream_字节缓冲输出流
  2. 入门案例中使用的组件介绍
  3. 使用匿名内部类创建线程
  4. 解读Redis报错:“MISCONF Redis is configured to save RDB snapshots”
  5. 数据库表设计、 数据库分层、myslq水平拆分、oracle表分区
  6. java cmd找不到文件_cmd中输入java找不到文件解决方法
  7. linux7配置开启防火墙,CentOS7防火墙设置
  8. sdram 时钟相位_stm32f429主频大于160MHz时,sdram数据不稳定
  9. JavaFX 中的像素、分辨率与缩放比
  10. 聊聊flink的Async I/O