使用asn1tools进行asn1编解码
最近在做3GPP的编解码,发现有两个第三方库比较好用。一个是ASN1C(c语言编译环境),一个是python第三方库asn1tools。这里介绍下asn1tools的使用方法:
1 第一步:生成asn文件
将需要编码的数据结构保存在asn后缀名的文件中
3GPP中的结构如下:
-- ASN1START
BCCH-BCH-Message-NB ::= SEQUENCE {
message BCCH-BCH-MessageType-NB
}
BCCH-BCH-MessageType-NB::= MasterInformationBlock-NB
-- ASN1STOP
对应的.asn文件的基本结构如下:也就是讲ASN1START和ASN1STOP中的数据提取出来。然后上asn自己的头信息
EUTRA-RRC-Definitions DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
BCCH-BCH-Message ::= SEQUENCE {
message BCCH-BCH-MessageType
}
END
在3GPP中有大量的类似结构,如果一个个手动的拷贝,太耗费时间了。因此用下面的代码将3GPP中的数据结构自动提取出来保存在asn文件中。代码如下:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main()
{
std::string output_file;
std::string input_file = "D:/code_block_prj/gen_asn/protol.txt";
std::cout<<input_file.c_str()<<std::endl;
int pos = input_file.find('.');
if (pos == std::string::npos )
{
output_file = input_file + ".asn";
}
else
{
output_file = input_file.substr(0,pos) + ".asn";
}
std::fstream input;
input.open(input_file.c_str(), std::fstream::in );
if ( input.fail() == true)
{
std::cout<<"Please check input file is correct !"<<std::endl;
return 1;
}
std::fstream output;
output.open(output_file.c_str(), std::fstream::out );
if ( output.fail() == true)
{
std::cout<<"The output file can not be created here !"<<std::endl;
return 1;
}
std::string input_line;
std::vector<std::string > vec_asn;
std::vector<std::string >::iterator itr;
const unsigned long cul_asn_idle = 0x0;
const unsigned long cul_asn_start = 0x1;
unsigned long asn_state = cul_asn_idle;
while ( std::getline(input, input_line) )
{
if ( cul_asn_idle == asn_state )
{
if ( input_line.find("-- ASN1START") != std::string::npos )
{
asn_state |= cul_asn_start;
}
continue;
}
if ( 0 != (cul_asn_start & asn_state) )
{
if ( input_line.find("-- ASN1STOP") != std::string::npos )
{
asn_state = cul_asn_idle;
}
else
{
vec_asn.push_back(input_line);
}
}
}
for ( itr = vec_asn.begin(); itr != vec_asn.end(); ++itr )
{
output<<*itr<<std::endl;
}
input.close();
output.close();
return 0;
}
2:打开36331的word文档并另存为txt文件
3:运行上面的程序,其中input_file就是保存txt文件的位置,需要自己设置。运行完后会在本地文件夹下面生成一个asn文件
第二步:利用asn1tools进行编解码:
一:首先pip3 install asn1tools进行模块安装
二:在3GPP中有大量的数据结构,例如sequence, bit string, octer string, bool, sequence of等等,这些结构体在python对应的结构体如下表。
ASN.1 type |
Python type |
Example |
||
BOOLEAN |
bool |
True 'ackNackSRS-SimultaneousTransmission': True |
||
INTEGER |
int |
87 'p0-NominalPUCCH': -127, |
||
REAL |
float |
33.12 |
||
NULL |
– |
None |
||
BIT STRING |
tuple(bytes, int) |
(b'\x50', 4) 元组第一个参数为值,第二个参数为bit长度 示例: ac-BarringForSpecialAC BIT STRING (SIZE(5)) 'ac-BarringForSpecialAC': (b'\xf0', 5) |
||
OCTET STRING |
bytes |
b'\x44\x1e\xff' hnb-Name OCTET STRING (SIZE(1..48)) 'hnb-Name': b'4' |
||
OBJECT IDENTIFIER |
str |
'1.33.2' |
||
ENUMERATED |
str |
'one' ac-BarringTime ENUMERATED {s4, s8, s16, s32, s64, s128, s256, s512}, 代码: 'ac-BarringTime': 's128', |
||
SEQUENCE |
dict |
{'a': 52, 'b': 1} |
||
SEQUENCE OF |
list |
[1, 3]采用list列表的方法[] 示例一: InterFreqCarrierFreqList ::= SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo
|
||
SET |
dict |
{'foo': 'bar'} |
||
SET OF |
list |
[3, 0, 7] |
||
CHOICE |
tuple |
('a', 5) |
||
UTF8String |
str |
'hello' |
||
NumericString |
str |
'234359' |
||
PrintableString |
str |
'goo' |
||
IA5String |
str |
'name' |
||
VisibleString |
str |
'gle' |
||
GeneralString |
str |
'abc' |
||
BMPString |
str |
'ko' |
||
GraphicString |
str |
'a b' |
||
TeletexString |
str |
'ßø' |
||
UniversalString |
str |
'åäö' |
||
UTCTime |
datetime.datetime |
datetime(2018, 6, 11) |
||
GeneralizedTime |
datetime.datetime |
datetime(2018, 1, 31) |
||
ObjectDescriptor |
– |
– |
三:对结构进行赋值。以BCCH-DL-SCH-Message-NB结构为例,首先需要根据BCCH-DL-SCH-Message-NB的结构用python的结构体进行赋值。如下所示。具体的赋值方法参考上面的表格。
BCCH_DL_SCH_Message_NB={
'message':(
'c1',(
'systemInformationBlockType1-r13',{
'hyperSFN-MSB-r13':(b'\x07',8),
'cellAccessRelatedInfo-r13':{
'plmn-IdentityList-r13':[
{'plmn-Identity-r13':{'mcc':[0,0,1],'mnc':[0,1]},
'cellReservedForOperatorUse-r13':'notReserved',
'attachWithoutPDN-Connectivity-r13':'true'}],
'trackingAreaCode-r13':(b'\x00\x01',16),
'cellIdentity-r13':(b'\x00\x01\x10\x10',28),
'cellBarred-r13':'notBarred',
'intraFreqReselection-r13':'notAllowed',
},
'cellSelectionInfo-r13':{
'q-RxLevMin-r13':-53,
'q-QualMin-r13':-20
},
'freqBandIndicator-r13':8,
'schedulingInfoList-r13':[{'si-Periodicity-r13':'rf64','si-RepetitionPattern-r13':'every8thRF','sib-MappingInfo-r13':[],'si-TB-r13':'b552'}],
'si-WindowLength-r13':'ms160'
}
)
)
}
四:进行编码。在encode函数中第一个参数就是asn文件中的结构体名称。第二个参数就是上面赋值的字典结构。最终得到16进制的码流
def asn1tools__3GPP():
foo = asn1tools.compile_files('protol.asn', 'uper')
encoded = foo.encode('BCCH-DL-SCH-Message-NB',BCCH_DL_SCH_Message_NB)
print(encoded.hex())
五:数据可视化:16进制的码流对于观测不方便。因此将前面编码得到的16进制码流再进行解码并保存在json文件中,然后通过jsonViewer工具进行查看。代码如下
class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, bytes):
return str(obj, encoding='utf-8');
return json.JSONEncoder.default(self, obj)
def asn1tools__3GPP():
foo = asn1tools.compile_files('protol.asn', 'uper')
encoded = foo.encode('BCCH-DL-SCH-Message-NB',BCCH_DL_SCH_Message_NB)
print(encoded.hex())
decoded=foo.decode('BCCH-DL-SCH-Message-NB',encoded)
value=json.dumps(decoded,indent=1,cls=MyEncoder,ensure_ascii=False)
print(decoded,value)
f=open('BCCH.json','wb')
f.write(value.encode("utf-8"))
f.close()
在jsonViewer中打开json文件,可以更直观的观测结构
但是这样会有一个问题,在编译BIT STRING或者OCTER STRING的时候,编译完后的数据无法写入json文件。原因在于json文件是utf-8的编码格式。某些字节utf-8无法识别,例如0x80这样的数据。如果将trackingAreaCode-r13改成如下的值,那么在写入json文件的时候就会提示utf-8 can’t decode \0x80的错误
'trackingAreaCode-r13':(b'\x80\x01',16),
那么代码修改如下。用uper和jer两种编码方式编译asn文件。然后将UPER解码得到的数据用jer的方法进行编码。然后再写入json文件。
def asn1tools__3GPP():
foo = asn1tools.compile_files('protol.asn', 'uper')
foo_jer=asn1tools.compile_files('protol.asn', 'jer')
encoded = foo.encode('BCCH-DL-SCH-Message-NB',BCCH_DL_SCH_Message_NB)
print(encoded.hex())
decoded=foo.decode('BCCH-DL-SCH-Message-NB',encoded)
value_jer = foo_jer.encode('BCCH-DL-SCH-Message-NB', decoded)
with open('BCCH.json','wb') as f:
f.write(value_jer)
这样做的原理是UPER是将数据以字节的形式编码,而jer是以字符串的形式编码。因此写入json文件没有任何问题。得到的结构数据如下。
使用asn1tools进行asn1编解码的更多相关文章
- iOS8系统H264视频硬件编解码说明
公司项目原因,接触了一下视频流H264的编解码知识,之前项目使用的是FFMpeg多媒体库,利用CPU做视频的编码和解码,俗称为软编软解.该方法比较通用,但是占用CPU资源,编解码效率不高.一般系统都会 ...
- IOS和Android支持的音频编解码
1.IOS编码 参考文档地址:https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/Multimedi ...
- java编解码技术,netty nio
对于java提供的对象输入输出流ObjectInputStream与ObjectOutputStream,可以直接把java对象作为可存储 的字节数组写入文件,也可以传输到网络上去.对与java开放人 ...
- 编解码-marshalling
JBoss的Marshalling序列化框架,它是JBoss内部使用的序列化框架,Netty提供了Marshalling编码和解码器,方便用户在Netty中使用Marshalling. JBoss M ...
- 编解码-protobuf
Google的Protobuf在业界非常流行,很多商业项目选择Protobuf作为编解码框架,Protobuf的优点. (1)在谷歌内部长期使用,产品成熟度高: (2)跨语言,支持多种语言,包括C++ ...
- 编解码-java序列化
大多数Java程序员接触到的第一种序列化或者编解码技术就是Java的默认序列化,只需要序列化的POJO对象实现java.io.Serializable接口,根据实际情况生成序列ID,这个类就能够通过j ...
- ilbc编解码
针对国内的博客或者技术论坛对 ILBC的论述都是把文章抄来抄去, 本人在此对 ILBC的具体代码实现详细列出代码. ILBC是由Global IP Sound公司提出的一种专为包交换网络通信设计的编解 ...
- 各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式
编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放 license收费等 ...
- 【GPU编解码】GPU硬解码---DXVA
前面介绍利用NVIDIA公司提供的CUVID库进行视频硬解码,下面将介绍利用DXVA进行硬解码. 一.DXVA介绍 DXVA是微软公司专门定制的视频加速规范,是一种接口规范.DXVA规范制定硬件加速解 ...
随机推荐
- 甲骨文Java Archive
甲骨文Java Archive 甲骨文Java Archive提供自助下载访问我们的一些历史的Java版本. 警告: 这些旧版本的JRE和JDK来帮助开发人员提供了在旧系统调试问题. 他们没有更新最新 ...
- HTML5 Canvas 用requestAnimation取代setInterval
<!DOCTYPE html> <html lang="utf-8"> <meta http-equiv="Content-Type&quo ...
- wps文档忘记保存关闭了怎么恢复
wps文档忘记保存关闭了怎么恢复 点击程序左上角的''WPS文字/表格/演示''选择备份管理,根据需要尝试右侧下面的"查看其他备份"功能就能找了. 点击"开始-运行&qu ...
- 51单片机 | 实现SMC1602液晶屏显示实例
———————————————————————————————————————————— LCD1602 - - - - - - - - - - - - - - - - - - - - - - - - ...
- 未能加载文件或程序集 MySql.Web
偶然间碰到这个错误,找到一个临时的解决办法,真正的原因还不知道是什么,也不知道这种解决方法会不会对以后有什么副作用. “/”应用程序中的服务器错误. 配置错误 说明: 在处理向该请求提供服务所需的配置 ...
- PowerShell-将CSV导入SQL Server
$database = 'foxdeploy' $server = '.' $table = 'dbo.powershell_test' Import-CSV .\yourcsv.csv | ForE ...
- 【转】GitHub入门详细讲解
第一:请登录https://windows.github.com/ 下载您需要的安装软件,进行安装.安装后桌面有:GitHub 和 Git Shell 第二: 申请一个帐号https://github ...
- Windows2008RC2 IIS配置php执行环境
1:下载一个php manager,安装.打开IIS管理器后,点击计算机,就能够看到右边PHPManager 静静地躺在那儿了.双击PHPManager 后我们就能够開始对PHP进行配置了. 2 ...
- sprint3 【每日scrum】 TD助手站立会议第八天
站立会议 组员 昨天 今天 困难 签到 刘铸辉 (组长) 调整闹钟和整个项目的显示效果,最后做出了微信界面滑动的显示效果 整合原来做过的功能,并做相应的改进,整合其他的功能 在界面的设计和用户交互上始 ...
- Android Studio 2.0 正式版公布啦 (首次中文翻译)
Android Studio 2.0 公布了,添加了一些新特性: 1. 更加完好的 Instant Run 2. 更快的 Android Emulator 3.GPU Debugger Preview ...