openssl堆栈

来源:互联网 发布:算法设计与分析pdf下载 编辑:程序博客网 时间:2024/06/05 01:51

一 openssl堆栈

堆栈是一种先进后出的数据结构。openssl大量采用堆栈来存放数据。
它实现了一个通用的堆栈,可以方便的存储任意数据。
它实现了许多基本的堆栈操作,主要有:堆栈拷贝(sk_dup)、构建新堆栈(sk_new_null,sk_new)、插入数据(sk_insert)、删除数据(sk_delete)、查找数据(sk_find,sk_find_ex)、入栈(sk_push)、出栈(sk_pop)、获取堆栈元素个数(sk_num)、获取堆栈值(sk_value)、设置堆栈值(sk_set)和堆栈排序(sk_sort)。
 
二 openssl堆栈数据结构
openssl堆栈数据结构在stack.h中定义如下:
  1. typedefstruct stack_st
  2. {
  3. int num;
  4. char**data;
  5. int sorted;
  6. int num_alloc;
  7. int(*comp)(constchar*const*,constchar*const*);
  8. }STACK;
各字段意义如下:
num:堆栈中存放数据的个数。
data:用于存放数据地址,每个数据地址存放在data[0]到data[num-1]中。
sorted:堆栈是否已排序,如果排序则值为1,否则为0,堆栈数据一般是无序的,只有当用户调用了sk_sort操作,其值才为1。
comp:堆栈内存放数据的比较函数地址,此函数用于排序和查找操作;当用户生成一个新堆栈时,可以指定comp为用户实现的一个比较函数;或当堆栈已经存在时通过调用sk_set_cmp_func函数来重新指定比较函数。
注意,用户不需要调用底层的堆栈函数(sk_sort、sk_set_cmp_func等),而是调用他通过宏实现的各个函数。
 
三 openssl堆栈源码
openssl堆栈实现源码位于crypto/stack目录下。下面分析了部分函数。
1、sk_set_cmp_func
此函数用于设置堆栈存放数据的比较函数。由于堆栈不知道用户存放的是什么数据,所以,比较函数必须由用户自己实现。
2、sk_find
根据数据地址来查找它在堆栈中的位置。当堆栈设置了比较函数时,它首先对堆栈进行排序,然后通过二分法进行查找。如果堆栈没有设置比较函数,它只是简单的比较数据地址来查找.
3、sk_sort
本函数对堆栈数据排序。它首先根据sorted来判断是否已经排序,如果未排序则调用了标准C函数qsort进行快速排序。
4、sk_pop_free
本函数用于释放堆栈内存放的数据以及堆栈本身,它需要一个由用户指定的针对具体数据的释放函数。如果用户仅调用sk_free函数,则只会释放堆栈本身所用的内存,而不会释放数据内存。
 
四 定义用户自己的堆栈函数
用户直接调用最底层的堆栈操作函数是一个麻烦的事情,对此openssl提供了用宏来帮助用户实现接口。用户可以参考safestack.h来定义自己的上层堆栈操作函数,举例如下,safestack.h定义了如下关于GENERAL_NAME数据结构的堆栈操作:
  1. #define sk_GENERAL_NAME_new(st) SKM_sk_new(GENERAL_NAME,(st))
  2. #define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME)
  3. #define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME,(st))
  4. #define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME,(st))
  5. #define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME,(st),(i))
  6. #define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME,(st),(i),(val))
  7. #define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME,(st))
  8. #define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME,(st),(val))
  9. #define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME,(st),(val))
  10. #define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME,(st),(val))
  11. #define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME,(st),(val))
  12. #define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME,(st),(i))
  13. #define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME,(st),(ptr))
  14. #define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME,(st),(val),(i))
  15. #define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME,(st),(cmp))
  16. #define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st)
  17. #define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME,(st),(free_func))
  18. #define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME,(st))
  19. #define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME,(st))
  20. #define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME,(st))
  21. #define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME,(st))
当用户想对GENERAL_NAME数据进行堆栈操作时,调用上面由宏定义的函数即可,即直观又方便。比如用户想设置堆栈数据的比较函数和对堆栈排序时,可分别调用:sk_GENERAL_NAME_set_cmp_func和sk_GENERAL_NAME_sort。
 
五 openssl堆栈编程实例
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<openssl/safestack.h>
  5. #define sk_Student_new(st) SKM_sk_new(Student,(st))
  6. #define sk_Student_new_null() SKM_sk_new_null(Student)
  7. #define sk_Student_free(st) SKM_sk_free(Student,(st))
  8. #define sk_Student_num(st) SKM_sk_num(Student,(st))
  9. #define sk_Student_value(st, i) SKM_sk_value(Student,(st),(i))
  10. #define sk_Student_set(st, i, val) SKM_sk_set(Student,(st),(i),(val))
  11. #define sk_Student_zero(st) SKM_sk_zero(Student,(st))
  12. #define sk_Student_push(st, val) SKM_sk_push(Student,(st),(val))
  13. #define sk_Student_unshift(st, val) SKM_sk_unshift(Student,(st),(val))
  14. #define sk_Student_find(st, val) SKM_sk_find(Student,(st),(val))
  15. #define sk_Student_delete(st, i) SKM_sk_delete(Student,(st),(i))
  16. #define sk_Student_delete_ptr(st, ptr) SKM_sk_delete_ptr(Student,(st),(ptr))
  17. #define sk_Student_insert(st, val, i) SKM_sk_insert(Student,(st),(val),(i))
  18. #define sk_Student_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(Student,(st),(cmp))
  19. #define sk_Student_dup(st) SKM_sk_dup(Student, st)
  20. #define sk_Student_pop_free(st, free_func) SKM_sk_pop_free(Student,(st),(free_func))
  21. #define sk_Student_shift(st) SKM_sk_shift(Student,(st))
  22. #define sk_Student_pop(st) SKM_sk_pop(Student,(st))
  23. #define sk_Student_sort(st) SKM_sk_sort(Student,(st))
  24. typedefstructStudent_st
  25. {
  26. char*name;
  27. int age;
  28. char*otherInfo;
  29. }Student;
  30. typedef STACK_OF(Student)Students;
  31. Student*Student_Malloc()
  32. {
  33. Student*a=malloc(sizeof(Student));
  34. a->name=(char*)malloc(sizeof(char)*20);
  35. strcpy(a->name,"zcp");
  36. a->otherInfo=(char*)malloc(sizeof(char)*20);
  37. strcpy(a->otherInfo,"no info");
  38. return a;
  39. }
  40. voidStudent_Free(Student*a)
  41. {
  42. free(a->name);
  43. free(a->otherInfo);
  44. free(a);
  45. }
  46. int main()
  47. {
  48. Students*s;
  49. Student*s1,*one;
  50. int i,num;
  51. s=sk_Student_new_null();/* 新建一个堆栈对象 */
  52. s1=Student_Malloc();
  53. sk_Student_push(s,s1);
  54. num=sk_Student_num(s);
  55. for(i=0; i<num; i++)
  56. {
  57. one=sk_Student_value(s,i);
  58. printf("student name : %s\n",one->name);
  59. printf("sutdent age : %d\n",one->age);
  60. printf("student otherinfo : %s\n\n\n",one->otherInfo);
  61. }
  62. sk_Student_pop_free(s,Student_Free);
  63. return0;
  64. }
运行结果
  1. [root@localhost ~]# cd /
  2. [root@localhost /]# cd /openssl-1.1.0c/test
  3. [root@localhost test]# gcc example1.c -o example1 -L/usr/lib -lssl -lcrypto
  4. [root@localhost test]#./example1
  5. student name : zcp
  6. sutdent age :1934268344
  7. student otherinfo : no info
 
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 10个月婴儿咳嗽怎么办 6个月婴儿感冒了怎么办 六个月宝宝有痰怎么办 9月婴儿牛奶过敏怎么办 一用粉底就过敏怎么办 7个月婴儿过敏怎么办 9个月宝宝腹泻怎么办 9个月宝宝拉肚子怎么办 5个月宝宝拉肚子怎么办 九个月大宝宝拉肚子怎么办 九个半月的宝宝拉肚子怎么办 9个月婴儿拉稀怎么办 九个月的宝宝拉肚子怎么办 9个月宝宝拉稀水怎么办 2岁宝宝腹泻拉水怎么办 18个月宝宝拉水怎么办 2个月宝宝拉稀水怎么办 2个月的宝宝腹泻怎么办 2个月的宝宝拉稀怎么办 宝宝不喝补液盐怎么办 4个月宝宝腹泻怎么办 6个月宝宝腹泻怎么办 四个月的宝宝拉肚子怎么办 7个月婴儿便秘怎么办 宝宝9个月拉肚子怎么办 2个月宝宝拉肚子怎么办 4个月宝宝没奶怎么办 宝宝又吐又拉怎么办 冬季车放在外面怎么办 冬天车放在外面怎么办 新车被拖走了要怎么办 门钥匙拔不出来怎么办 婴儿换尿布就哭怎么办 芥末吃多了胃疼怎么办 孕妇吃了甜白酒怎么办 43岁意外怀二胎怎么办 38岁意外怀二胎怎么办 脚崴了没有肿怎么办 我出轨了怎么办很痛苦 老公有了小三老婆应该怎么办 厦门学生卡丢了怎么办