最近在做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

#include

#include

#include

using namespace std;

int main()

{

std::string output_file;

std::string input_file = "D:/code_block_prj/gen_asn/protol.txt";

std::cout<

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<

return 1;

}

std::fstream output;

output.open(output_file.c_str(), std::fstream::out );

if ( output.fail() == true)

{

std::cout<

return 1;

}

std::string input_line;

std::vector<:string> vec_asn;

std::vector<: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<

}

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

‘interFreqCarrierFreqList‘: [‘dl-CarrierFreq‘: 1,

‘q-RxLevMin‘: -45,

‘t-ReselectionEUTRA‘: 0,

‘threshX-High‘: 31,

‘threshX-Low‘: 29,

‘allowedMeasBandwidth‘: ‘mbw6‘,

‘presenceAntennaPort1‘: True,

‘neighCellConfig‘: (b‘\x00‘, 2),

‘q-OffsetFreq‘: ‘dB0]

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文件没有任何问题。得到的结构数据如下。

python解码asn_使用asn1tools进行asn1编解码相关推荐

  1. 视频编解码(十八):编解码linux测试步骤

    一.编码测试 1)持续工作 ./demoVencoder -i /mnt/video/h264/720p-30zhen.yuv -o /mnt/video/h264/720p.h264 -f 0 -s ...

  2. 图片解码 java_Java 8实现图片BASE64编解码

    前言 Basic编码是标准的BASE64编码,用于处理常规的需求:输出的内容不添加换行符,而且输出的内容由字母加数字组成. 最近做了个Web模版,其中想用Base64背景图.虽然网络上有现成的编码器, ...

  3. Jva编解码,加密工具类大全(Base64编解码,URL 编解码,sha56_Hmac加密,MD5对字符串进行加密,java自带类实现SHA-256方式加密)

    Base64编解码 /*** Base64编码.*/public static String encodeBase64(byte[] input) {return new String(Base64. ...

  4. 【PYTHON小项目】VCF文件转EXCEL文件方法详解(附QUOTED-PRINTABLE编解码)

    来源 整理大量通讯录时,发现从手机上下载的CSV文件不易转成EXCEL文件(QQ通讯录和百度云盘都试过了,CSV文件过大无法加载),导致整理起来特别麻烦,故试图自己写一个小程序来处理文件. 分析CSV ...

  5. Netty之编解码技术(四)

    通常我们习惯将编码(Encode)称为序列化(serialization),它将对象序列化为字节数组,用于网络传输.数据持久化或者其它用途. 反之,解码(Decode)称为反序列化(deseriali ...

  6. 【数据压缩(五)】LZW编解码c语言实现和分析

    一.实验目的 1.掌握词典编码的基本原理 2.C/C++/Python等语言编程实现LZW解码器 3.分析编解码算法 二.实验要求 1.首先调试LZW的编码程序,以一个文本文件作为输入,得到输出的LZ ...

  7. Netty系列之Netty编解码框架分析

    1. 背景 1.1. 编解码技术 通常我们也习惯将编码(Encode)称为序列化(serialization),它将对象序列化为字节数组,用于网络传输.数据持久化或者其它用途. 反之,解码(Decod ...

  8. java实现asn.1解码_ASN1编解码实现方法

    第1章概述 1.1背景 系统与充值平台的接口是文件的方式,充值平台将文件内容以ASN.1方式进行编码,系统需要根据ASN.1协议进行解码. 关于ASN.1开发的资料,网上资料非常少,特别是涉及到具体的 ...

  9. java asn.1_ASN1编解码实现方法 | 学步园

    第1章概述 1.1背景 系统与充值平台的接口是文件的方式,充值平台将文件内容以ASN.1方式进行编码,系统需要根据ASN.1协议进行解码. 关于ASN.1开发的资料,网上资料非常少,特别是涉及到具体的 ...

最新文章

  1. sql Escape用法
  2. [SQL基础教程]1-4 SQL 表的创建
  3. 管理和维护RHCS集群
  4. ReplicaStateMachine分析
  5. 【渝粤教育】国家开放大学2018年秋季 0708-22T互联网创业基础 参考试题
  6. linux安装vnc
  7. astar插件下载 就行_premiere软件下载安装pr自学视频教程
  8. 关注程序员健康,使用中医十二经络来解释一个神奇的梦境!
  9. Swift-字符串和字符
  10. 微信小程序重新发起请求加载页面
  11. 小巧的menuetOS
  12. c语言生成excel文件简书,通过xlwings生成Excel文件
  13. 科技“蝶变”,两轮电动车下一个五年的“新动力”
  14. 优化篇-图片动态转图
  15. 机器学习笔记--PR曲线和ROC曲线
  16. IDEA日常填坑:Cannot resolve plugin org.apache.maven.plugins:maven-war-plugin
  17. Android开发案例Onclick点击事件switch调用分类04
  18. 2019 大数据必备书籍推荐
  19. 基于STM32F103的步进电机(ULN2003/28BYJ-48)角度和转速控制详细资料和驱动代码
  20. WIN10系统如何关闭139 135 445端口

热门文章

  1. oracle写会阻塞读吗,一致性读保证了读不阻塞写
  2. 以下用来处理python字典的方法中正确的是_以下关于Python的说法中正确的是哪一项?...
  3. Python批量处理文件、图片、视频【干货建议收藏】
  4. 【404 App】v2.0版本各个渠道统计
  5. 响应式图片img中的srcset和sizes
  6. Zabbix监控系统(一):初识Zabbix
  7. 计算机控制机床系统设计,基于线切割机床的电机控制系统设计与实现
  8. TuGraph开源JAVA客户端工具TuGraph-OGM,无缝对接JAVA开发生态
  9. 贝达药业拟在香港上市:超90%收入来自埃克替尼,市值已大幅缩水
  10. 成为Java高级架构师必看的15本书