python - asn1 将文本解析为 json

python - asn1 parsed text to json

有了这个link中给出的文本,需要提取数据如下

  1. 每条记录都以 YYYY Mmm dd hh:mm:ss.ms 开头,例如 2019 Aug 31 09:17:36.550
  2. 每条记录都有一个 header 从上面的第 1 行开始到一个空行结束
  3. 记录数据包含在下面的行中Interpreted PDU:
  4. 感兴趣的记录是记录 header 第一行有 0xB821 NR5G RRC OTA Packet -- RRC_RECONFIG
  5. 的记录

是否可以提取所选记录 headers 和上面 #3 以下的文本作为嵌套 json 的数组,格式如下 - 为简洁起见,确实需要整个文本数据为 JSON.

data = [{"time": "2019 Aug 31  09:17:36.550", "PDU Number": "RRC_RECONFIG Message", "Physical Cell ID": 0, "rrc-TransactionIdentifier": 1, "criticalExtensions rrcReconfiguration": {"secondaryCellGroup": {"cellGroupId": 1, "rlc-BearerToAddModList": [{"logicalChannelIdentity": 1, "servedRadioBearer drb-Identity": 2, "rlc-Config am": {"ul-AM-RLC": {"sn-FieldLength": "size18", "t-PollRetransmit": "ms40", "pollPDU": "p32", "pollByte": "kB25", "maxRetxThreshold": "t32"}, "dl-AM-RLC": {"sn-FieldLength": "size18", "t-Reassembly": "ms40", "t-StatusProhibit": "ms20"}}}]}}  }, next records data here]

请注意,输入文本是 3GPP 38.331 section 6.3.2. I'm not sure normal python text parsing is the right way to handle this or should one use something like asn1tools 库中 ASN1 数据规范的解析输出?如果是这样,对此数据的示例用法将会有所帮助。

不幸的是,不太可能有人会直接回答您的问题(这与 非常相似)

您 link 的文本显然是一个日志文件,其中使用 ASN.1 值表示法使消息易于阅读。因此,尝试从文本形式解码这些消息是不寻常的,您可能找不到相应的工具。

理论上,通用方法应该是这个:

  1. 收集用于创建 ASN.1 消息的 ASN.1 定义(模式)
  2. 使用 ASN.1 工具(也称为编译器)编译这些定义,以生成您喜欢的语言的对象模型 (python)。该工具将提供用于编码和解码的特定代码……您将使用 ASN.1 值解码器。
  3. 添加您的自定义代码(添加到对象模型或插入 ASN.1 编译器)以编码您的 JSON 对象

如你所见,这是一个很长的镜头(如果这个解释太短或不清楚,我可以扩展)

除非你的任务是重复性的and/or消息的数量很大,尝试你已经知道的方法(手动搜索,正则表达式)来搜索日志文件。

如果您想了解创建 ASN.1 工具需要什么,您可以找到一些(不是很多,因为 ASN.1 不是特别年轻和流行)。查看 https://github.com/etingof/pyasn1 (python)

为了好玩,我在 Java 中创建了自己的解码器,并添加了 ASN.1 值解码器来说明我的答案:https://github.com/yafred/asn1-tool(分支文本 asn 值支持)

鉴于您有输入数据的文本表示,您可以查看 parse 库。这允许您在字符串中查找模式并将内容分配给变量。

下面是提取时间、PDU 编号和物理小区 ID 数据字段的示例:

import parse

with open('w9s2MJK4.txt', 'r') as f:
  input = f.read()

data = []
pattern = parse.compile('\n{year:d} {month:w} {day:d}  {hour:d}:{min:d}:{sec:d}.{ms:d}{}Physical Cell ID = {pcid:d}{}PDU Number = {pdu:w} {pdutype:w}')

for s in pattern.findall(input):
  record = {}
  record['time'] = '{} {} {} {:02d}:{:02d}:{:02d}.{:03d}'.format(s.named['year'], s.named['month'], s.named['day'], s.named['hour'], s.named['min'], s.named['sec'], s.named['ms'])
  record['PDU Number'] = '{} {}'.format(s.named['pdu'], s.named['pdutype'])
  record['Physical Cell ID'] = s.named['pcid']
  data.append(record)

由于您的结构相当复杂且数据字段很多,这可能会变得有点麻烦,但我个人更喜欢这种方法而不是正则表达式。也许还有一种更聪明的方法来解析日期(不幸的是,它似乎没有图书馆支持的标准格式之一)。