首页 > 代码库 > 【密码工程】asn1——asn1c、javaAsn1Comilper、protobuf的使用示例

【密码工程】asn1——asn1c、javaAsn1Comilper、protobuf的使用示例

1 使用asn1c实现编码

参考网址:http://lengxuezhixuan.blog.chinaunix.net/uid-28765492-id-3765759.html

PS:这个网址就是根据下载的asn1c中的英文指导文档做的

* 遇到的问题:

(1)头文件的引用:头文件放在了vc/include下,对.h文件可以使用include<>。对于本工程下的.h文件使用include""

(2)如果cpp与c文件共存,会有预编译头不兼容的问题,可以设置所有源文件的属性去掉预编译头,或者将所有代码调整成cpp或c

****************************************************************************************************

本人所做的实验是用c编码、用java解码:将编码结果直接用%s输出到txt文件,之后用java解码就实现了不同语言间序列化数据的使用(其实都用不到asn文件,用c编码时只是需要利用asn文件生成那一系列c文件;解码就更不需要asn了)

PS:之后编了一个复杂的,各种报错类型找不到,浪费了一个小时才发现asn-0.9.21的类型定义名称和网上的不一样(要去sketon里面找),好坑。编码时自己设计的结构名name会被typedef成name_t!

=============================================================

2 使用javaAsn1Comilper解码(参考javaAsn1Comilper指导文档的示例

(1)TestUtil是一个示例,可以不要(里面有结构化输出,可以直接copy一下);TestParser也可以不要,需要同时删掉另外一个继承了它的类

(2)为自己设计的结构里的元素分别创建类,并分别继承相应的类型:为rectangle的内容创建一个类width(继承ASN1Integer)

package com.chaosinmotion.asn1;


public class width extends ASN1Integer {

public width(){//默认是5

super(5);

}

public width(long value){//设置大小

super(value);

}

}

(3)创建自己设计的那个结构的类:创建类Rectangle。必须用super.addElement为结构添加元素,否则该结构里啥也没有

package com.chaosinmotion.asn1;

public class BerRectangle extends Sequence {

public ASN1Integer length=new width();

public ASN1Integer width=new width();

public BerRectangle() {

super();

setUp();//必须使用addElement为sequence添加内容,否则成为未初始化

}

protected void setUp(){

super.addElement(length);

super.addElement(width);

}

}

(4)实现应用:就按文档给的来!

public static void main(String[] args){

    BerRectangle test=new BerRectangle();//创建对象

    test.width.setValue(23);//初始化对象

    test.length.setValue(42);

    //将对象编码

    ByteArrayOutputStream stream=new ByteArrayOutputStream();//必有

    BerOutputStream out=new BerOutputStream(stream);//必有

    try {

test.encode(out);//必有

            printData(stream.toByteArray());//copy的TestUtil的结构化输出方法

} catch (IOException e) {

// TODO Auto-generated catch block

System.out.println("error");

e.printStackTrace();

}

//解码    

    ByteArrayInputStream destream=new ByteArrayInputStream(stream.toByteArray());

    BerInputStream in=new BerInputStream(destream);

    BerRectangle test2=new BerRectangle();//必有,创建一个实体

    try {

test2.decode(in);//必有,in其实就是编码好的那串二进制,所以也可以是从文件读来;将in解码并放到test2中

            System.out.println(test2);//直接输出就可以

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println("over");

    }


=============================================================

3 protobuf实现asn1

首先,protobuf安装(系统环境:windows)

(参考protobuf源码的README.md,无调整)

1 安装cmake

网址:https://cmake.org/download/

本人直接下载的installer :)

2 安装git

网址:https://git-scm.com/download/win

同样,直接下载的二进制版本的,点击&finish :)

3 安装protobuf

 3.1按照readme的指示

3.1.1 设置cmake和git的使用路径

本人要将protobuf安装在"f:\新建文件夹"里,set PATH是设置临时环境变量

f:

cd 新建文件夹

set PATH=%PATH%;"c:\Program Files (x86)\Cmake\bin"

set PATH=%PATH%;"c:\Program Files\Git\cmd"

3.1.2 获得protobuf源码:本人下载的master版的

git clone -b master https://github.com/google/protobuf.git

 3.1.3 获得gmock(反正protobuf readme这么说的)

cd protobuf

git clone -b release-1.7.0 https://github.com/google/googlemock.git gmock

cd gmock

git clone -b release-1.7.0 https://github.com/google/googletest.git gtest

 3.1.4 使用cmake制作sln(可以用图形化的,也可以用命令行——本人的编译器是vs2010)

(1)本人用的图形化版的cmake来生成IDE使用的sln

source是protobuf/cmake;dst是protobuf/cmake/build/Debug(build/Debug是自己设的路径,为了做错时好删).

generate前先点击file的delete cache;然后configue,然后generate。

完成后就可以在Debug里找到protobuf.sln

(2) 命令行生成sln:

语句如下:

cmake -G "Visual Studio 10 2010 Win64" ^

 -DCMAKE_BUILD_TYPE=Debug ^

 -DCMAKE_INSTALL_PREFIX=../../../../install ^

../.. ^

 -DCMAKE_CXX_COMPILER="F:/Program Files (x86)/Microsoft Visual Studio 10.0/VC/bin/cl.exe" ^

 -DCMAKE_C_COMPILER="F:/Program Files (x86)/Microsoft Visual Studio 10.0/VC/bin/cl.exe"

 

本人的IDE是vs2010 win64的(可以用cmake --help查看cmake支持的IDE种类);生成类型是Debug(与文件名无关);

最后两行是设置c和cxx编译器地址,即IDE文件夹中的cl.exe的绝对路径;

(如果提示mspdb100.dll找不到,需要path=%path%;F:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE)

注意:输入路径时注意一定用/(cmake语法)和""(因为用空格断句,所以路径里有空格要用""包起来)。 

3.1.5 编译,可以使用IDE打开protobuf.sln直接build solution(因为命令行不好做,所以本菜鸟就用了IDE)

3.1.6 安装,打开protobuf.sln 

(1)首先build 整个solution 

(2)build 三个:libprotobuf,libprotoc,libprotobuf-lite,protoc;结果会在工程目录下的Debug中(protoc.exe libprotobuf-lite.lib libprotobufd.lib libprotocd.lib)

PS:readme中让build install,但我只在使用master版是成功过一次,之后一直失败,不知道怎么办,但是不影响应用也就没管(懒)

 3.2 按照网上的教程也是一样的,只是不用git,直接手动去网站下载;网址:https://developers.google.com/protocol-buffers/docs/downloads。

网上使用的版本中都有vsproject目录,所以可以直接进行3.1.5;但我下载的版本里面都没有现成的vsproject,需要自己生成,所以cmake、gmock还是要装的,只是省掉了2和3.1.2

=============================================================

protobuf的应用(win&&c++)

1 编写proto文件

本人编了一个最简单的例子,具体语法什么的可以去网上找。

message rectangle{

required int32 height = 1;

required int32 width = 2;

}

2 生成.cc和.h文件

cmd命令:protoc -I=C:\Users\chris\Desktop\ --cpp_out=C:\1 C:\Users\chris\Desktop\rectangle.proto

说明:

C:\Users\chris\Desktop\ 是我的proto文件所在目录

C:\1 是目标目录

C:\Users\chris\Desktop\rectangle.proto 是proto文件的绝对路径

3 创建一个工程

 3.1 添加protobuf的支持文件

protobuf/src/google和编译源码时生成的libprotobuf-lite.lib libprotobufd.lib libprotocd.lib

头文件使用<>,因此需要将google添加到编译器的vc/include目录下(本人初始不知道<>是这个意思,尝试将<>改为"",但总是失败,最后放弃)

将libprotobuf-lite.lib libprotobufd.lib libprotocd.lib添加到工程目录下,使用绝对路径加载(当然也有别的办法,本人。。懒)

 3.2 将之前生成的.cc和.h放进来

 3.3 编写main函数对rectangle进行应用

#include "rectangle.pb.h" 

#include <iostream>

#include <string>

using namespace std; 

#pragma comment(lib,"C:\\Users\\chris\\Desktop\\protodemo\\protodemo\\libprotocd.lib")

#pragma comment(lib,"C:\\Users\\chris\\Desktop\\protodemo\\protodemo\\libprotobufd.lib")

//#pragma comment(lib,"C:\\Users\\chris\\Desktop\\protodemo\\protodemo\\libprotobufd-lite.lib")

int main(int,char**){

rectangle test1,test2;

string data;

//初始化test1

test1.set_height(42);

test1.set_width(23);

test1.SerializeToString(&data);//对test1进行编码,结果放在data中


test2.ParseFromString(data);//将序列data解码,结果赋给test2


cout<<data<<"\n"<<"test2\n hieght:"<<test2.height()<<"\n width:"<<test2.width()<<"\n";

return 0;

}

PS:使用的头文件、lib、用于生成.cc和.h的protoc的版本要一致;创建的工程的propertis->c/c++->code generation的runtime改为MTD

=============================================================


本文出自 “12746634” 博客,请务必保留此出处http://12756634.blog.51cto.com/12746634/1942056

【密码工程】asn1——asn1c、javaAsn1Comilper、protobuf的使用示例