【密碼工程】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

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章