学习学习

《openssl 编程》之 文本数据库

上一篇 / 下一篇  2007-11-15 10:06:05 / 个人分类:信息安全

第十章  文本数据库

10.1 概述

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

#c }bpenU0

赵春平   28   湖北LUPA开源社区C sn-V$GGr@

      zcp 28   荆门

?(T d w-Cc T l+OW0

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

/I3Q4Sg^Q5e0

10.2 数据结构

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

%eP4t:Vi"@1o0

      typedef struct txt_db_st

G^&j!S/s0

      {

7e k,GT xG:\:B0

             int num_fields;

&J+Z#|w3V0

             STACK *data;LUPA开源社区DP7M!e*av1Z

             LHASH **index;LUPA开源社区)T#rF7V,g

             int (**qual)(char **);LUPA开源社区#sh*Uc;`k*R&V_

             long error;

xT?){p0

             long arg1;LUPA开源社区 dX*|1Fz.Xu

             long arg2;LUPA开源社区w;HG,Mc#SG:e

             char **arg_row;

A Q1Dr)I"F i3F6x.X0

      } TXT_DB;LUPA开源社区i1\1h:Rj

      意义如下:

.umDyNJ{r8c\0

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

7{`6y ew-c0

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

O&?,{-g2\Ex0

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

3]+^&_ g \;v8e#FP0

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

(o{4o&^7U@a Z^ F0

errorarg1arg2arg_row用于存放错误信息。

1r | sb` I8aO0

10.3 函数说明

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

DX5Mp9L4lxd0

用于从BIO中读入数据,转换为TXT_DBnum用于明确指明列数,本函数不建立哈希表。LUPA开源社区1O3Y GK7d*c4kT

2 long TXT_DB_write(BIO *out, TXT_DB *db)LUPA开源社区Y)ejU6fd I

            TXT_DB内容写入BIOLUPA开源社区.~oD{S p

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

Ua&s0V,J'd0c [0

            LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)LUPA开源社区9p@jnK%T O c

field指定的列建立哈希表。db为需要建索引的TXT_DBhash为一行数据的hash运算回调函数,cmp为一行数据的比较函数。LUPA开源社区8]&D$A |VZ9CY K

4 char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value)LUPA开源社区j0tg-giW

根据关键字段来查询数据,查询结果返回一行数据db为文本数据库,idx表明采用哪一列的哈希表来查找;value为查询条件。LUPA开源社区fF9y*L$a T kb

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

;o/YRD b0

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

"] E5D1p^;f1t)o0

6)   void TXT_DB_free(TXT_DB *db)

k'q(p/Cm0

             清除TXT_DB

J4T:ztM-QD0Wg4Ek0

10.4 编程示例

      /* txtdb.dat的内容

`/m {3gj t'p^0

      赵春平   28   湖北      LUPA开源社区|g-a$P Tl U*y

      zcp 28   荆门      

2\@:YSOb0

      */

Q`D+E"P$d0

      #include <openssl/bio.h>LUPA开源社区a1?mIl1a]9K4U

      #include <openssl/txt_db.h>

0H,O^*Rs3@r+AS]']B0

      #include <openssl/lhash.h>LUPA开源社区)X^"o2|K%@z

      

3C1u |L5j:A0

      /*名字过滤*/

4T@uR+~8UJ+n0

      static      int   name_filter(char **in)LUPA开源社区3q.[8L(DP K|wT/t+yz

      {

#RxMdfz}h*w0

             if(strlen(in[0])<2)LUPA开源社区E@$~rSh

                    return 0;LUPA开源社区K^TB.l3l

             return 1;LUPA开源社区#Q^R)wIZo1C dx

      }LUPA开源社区)CD H9~PW

 

1J\o} c7[J{,C&S0

      static unsigned long index_name_hash(const char **a)

(R"t!E,O:P0

      {

*P8B3F rSb0

             const char *n;

z&F!?`0P^z4J@0

      

;BN aD.t,Z!y0

          n=a[0];LUPA开源社区2@cj\)Ht@-S9Ael

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

@$YhP u8@ ^r {0

          return(lh_strhash(n));

,CK.IQ!]&V&wcM0

      }LUPA开源社区;V| yK3J'V

      

R|4S3ea7U(| ZH0

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

N{:Dy:k6Ql N#h0

      {

t;BP9G og\0

            const char *aa,*bb;

6\u ^m2Tv0

      LUPA开源社区^0|oMBllYb

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

^RP6v-Z hP1EWi0

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

gDcW+Zv0

            return(strcmp(aa,bb));

qq i5wx4? MX|0

      }

+jB p3U0G ?8r0

      LUPA开源社区u#W+\]f6F,uoa*R

      int   main()LUPA开源社区h!z+C`I:BQ1Y

      {

EY6KGD7d.g%Ju0

             TXT_DB       *db=NULL,*out=NULL;

+flR$psF%O-K0

             BIO              *in;

i;u*~ A/`A0

             int                 num,ret;LUPA开源社区._Q0K]/Qa1j

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

*FR[Ut `+kx4eL S!N0

      LUPA开源社区k4~1{zi!e%t9l

             in=BIO_new_file("txtdb.dat","r");LUPA开源社区~[8Oa*d g(ue,b

             num=1024;

CJTg+y$mQ?0

             db=TXT_DB_read(in,4);

}Y.ZA2L6g0

      LUPA开源社区1q3H-x|ji4S

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

/pJ.p"Go M&z&Q t \ n_O0

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

S6hj#y3d'n ZK#p0

             #if 1LUPA开源社区!@XBy.Ikz1S%{S

             strcpy(added[0],"skp");LUPA开源社区!s.f s]iZ:x;c

             #elseLUPA开源社区iC8W:dx1JeMfxU C@4U

             strcpy(added[0],"a");    /*不能插入名字对应的哈希表*/LUPA开源社区^ `.Zok*]

             #endif

PBX'v Ly0

             

+nAD3u)vbsEQ+H-k0

             added[1]=(char *)OPENSSL_malloc(10);LUPA开源社区F| O$e(P"VV

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

F{g]&A d0

      LUPA开源社区/I/Tal6^vs3G6u

             added[2]=(char *)OPENSSL_malloc(10);LUPA开源社区 yU^#T$A"RtU.f

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

Ux,e8j'l c4ap0

         

m CAt_OA0

             added[3]=NULL;

7G{*KxR S0opzC%`5x0

      LUPA开源社区 Dn}gk:N

             ret=TXT_DB_insert(db,added);

W8jyn0h0

             if(ret!=1)LUPA开源社区o i+m8X!f?L

             {

&B3h9I_#Yjt%m}V B4B0

                    printf("err!\n");

2Wvx2S%VV'Yb0

                    return -1;

C DmJ gw*F0

             }

2tLF |{s'j j0

             ret=TXT_DB_create_index(db,0, name_filter,index_name_hash,index_name_cmp);LUPA开源社区n5qJ$d OCTn

             if(ret!=1)LUPA开源社区yB'U{3otm

             {LUPA开源社区"H+m)l&gpFW

                    printf("err\n");

8|#v(|-O l#k0

                    return 0;LUPA开源社区.{XfB%rrg2_

             }LUPA开源社区v7|a?5xI+VR

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

U C4z Kl,f#K-V&|0

               row[0]=(char *)malloc(10);LUPA开源社区OC:ePh,^wv#J1~

             strcpy(row[0],"skp");LUPA开源社区;~L1P/F @

             row[1]=NULL;LUPA开源社区3|bCz|`:w$a%xgn#W

             rrow=TXT_DB_get_by_index(db,0,row);LUPA开源社区z!^"L3{*WWp

             if(rrow!=NULL)LUPA开源社区u K"` @AE{7WJ"o

                    printf("%s     %s  %s\n",rrow[0],rrow[1],rrow[2]);LUPA开源社区9W Y w'I`)o;DrK o*_

             out=BIO_new_file("txtdb2.dat","w");LUPA开源社区7jy*Vp DQ \9]

             ret=TXT_DB_write(out,db);LUPA开源社区[K Zp!Z!Ya`

             TXT_DB_free(db);

%RRmn+{~9j0

             BIO_free(in);LUPA开源社区;r,\Y'e4v1E

             BIO_free(out);LUPA开源社区}b ~#yX0S Bi

             return 0;

mu}LTIPT%K0

      }

M6y0e&g#w7k5j0

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

"u4VS x6Aq!v'{e0

 

v,^2|&k&V4A^V0

 LUPA开源社区8CtV9G(~l

 LUPA开源社区9B$A;[@.T;}rx OB


TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2008-08-20  
     12
3456789
10111213141516
17181920212223
24252627282930
31      

数据统计

  • 访问量: 23024
  • 日志数: 54
  • 图片数: 1
  • 文件数: 1
  • 建立时间: 2006-05-07
  • 更新时间: 2008-08-06

RSS订阅

Open Toolbar