175210课设第三次报告
Posted mtzf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了175210课设第三次报告相关的知识,希望对你有一定的参考价值。
本周计划
- 使用
openssl
原生 api 解析asn.1
编码文件 - 图形界面的勾画( QT5 )
完成情况
一、使用 openssl api
解析 asn.1
编码文件
有一个命令行工具叫做 openssl ans1parser
,它使用的是 ASN1_parse_dump
函数,具体如下
int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump);
BIO
是 openssl
自定义的 IO 流,pp
指向要解析的文件。indent
用来设置打印出来列之间空格个数,ident
越小,打印内容越紧凑。dump
指明当类型为 BIT STRING
或 OCTET STRING
时,打印内容的字节数。
1.1 所以先要学习 Bio
文档和源码很容易搜到,这里放小例子和注释
mem bio
#include <openssl/bio.h>
#include <openssl/asn1.h>
int main()
{
BIO *bio = BIO_new(BIO_s_mem()); // 生成一个mem类型的BIO
int len = BIO_write(bio, "mtmtmtmt", 6); // 将字符串写入 bio, 写 6 个字节
len = BIO_printf(bio, "%s", "lyzlyzlyz"); // 也可以指定格式类型写入
len = BIO_ctrl_pending(bio); // 得到 bio 缓冲区中待读的大小,只对 mem 类型的有效
char *out = (char*)OPENSSL_malloc(len);
BIO_read(bio, out, len); // 将 bio 中的内容读入 out 缓冲区中
printf("%s
", out);
OPENSSL_free(out); // 记着释放内存
BIO_free(bio);
return 0;
}
编译的时候别忘了加上 -lcrypto
链接库
file bio
#include <openssl/bio.h>
int main()
{
BIO *bio = BIO_new_file("mt.txt", "w");
BIO_write(bio, "mtmtmt", 4);
BIO_free(bio);
bio = BIO_new_file("mt.txt", "r");
char *out = (char*)OPENSSL_malloc(100);
int len = 1, outlen = 0;
while (len > 0)
{
len = BIO_read(bio, out + outlen, 1);
outlen += len;
}
printf("%s
", out);
BIO_free(bio);
OPENSSL_free(out);
return 0;
}
正常人看懂了第一个程序就能看懂第二个,不解释了
1.2 使用 ASN1_parse_dump
函数
解析 asn.1
编码文件,并将解析后的结果写入 BIO
流中。具体参数解释见上文
读取并解析上篇文章中的 rubytest.der
#include <openssl/bio.h>
#include <openssl/asn1.h>
int main()
{
BIO *bio = BIO_new(BIO_s_mem()); // 选择 file, socket 模式都可以,这里选择 mem 是为了迎合 qt 的操作
// BIO_set_fp 函数可以为 bio 绑定输出流,如 stdout
FILE *fp = fopen("rubytest.der", "rb");
if (fp == NULL)
{
printf("%s", "fail to open file");
return -1;
}
unsigned char buf[5000];
long len = fread(buf, 1, 5000, fp); // 将待解析的内容读入 buf 中,返回内容长度
fclose(fp);
ASN1_parse_dump(bio, buf, len, 7, 20); // 解析 buf 中的数据并写入 bio 流
int length = BIO_ctrl_pending(bio); // bio 中数据的长度
char *out = (char*)OPENSSL_malloc(length);
BIO_read(bio, out, length); // 将解析后的结果输入 out 中
printf("%s
", out);
OPENSSL_free(out);
BIO_free(bio);
return 0;
}
二、QT5 编写界面
本来准备用 electron
的,但我懒得整 nodejs
调用 c
了。而且用 css + js
写出个可以折叠的树型结构,想想就恶心……
入门 qt
,推荐这个知乎专栏
https://zhuanlan.zhihu.com/p/28472916。把信号,槽看看就差不多了,其他就是包装后的 c++
。
2.1 交互问题
BIO 流转 char*
,char*
转 QString。我写的函数如下:
QString MainWindow::parseAsn1(QString filename)
{
std::string file_name = filename.toStdString();
const char* fileName = file_name.c_str();
// 以上两行是将 QString 类型的 文件名 转为 c 语言的 char* 类型
FILE *fp = fopen(fileName, "rb");
unsigned char buf[5000];
int len = fread(buf, 1, 5000, fp);
fclose(fp);
BIO *bp = BIO_new(BIO_s_mem());
ASN1_parse_dump(bp, buf, len, 7, 20);
len = BIO_ctrl_pending(bp);
char *out = (char*)OPENSSL_malloc(len);
len = BIO_read(bp, out, len);
BIO_free(bp);
QString re = QString(out); // 再将 char* 类型转为 QString
OPENSSL_free(out);
qDebug() << re;
return re;
}
2.2 树状结构
使用 TreeWidget
组件,这个在此没法具体说。网上资料很多,跟着做就行。
2.3 qt 编译
因为调用了 openssl
库,需要在项目的 .pro
文件中添加
INCLUDEPATH += $$quote(/usr/include/openssl)
LIBS += $$quote(/usr/lib/x86_64-linux-gnu/libcrypto.so)
LIBS += $$quote(/usr/lib/x86_64-linux-gnu/libssl.so)
将 openssl
的头文件和动态链接库路径添加到项目配置中。
总结
做的很开心
以上是关于175210课设第三次报告的主要内容,如果未能解决你的问题,请参考以下文章