I am writing a a python script that takes a JSON file encoded in JER and convert it to UPER but I couldn't find a direct way to do this using the asn1tools.
ASN File: schema.asn
Schema DEFINITIONS ::= BEGIN
User ::= SEQUENCE {
firstName IA5String,
lastName IA5String,
id ID
}
ID ::= CHOICE {
userName IA5String,
userEmail IA5String
}
END
JSON File: user.json
{
"firstName": "John",
"lastName": "Doe",
"id": ["userName", "johndoe"]
}
Python File: script.py
import json
import asn1tools
schema = asn1tools.compile_files('schema.asn', codec='uper')
with open('user.json') as jer:
schema.encode('User', json.load(jer))
I am getting the following error:
Traceback (most recent call last):
File "/home/bijesh/playground/asn1_decoder/temp/script.py", line 7, in <module>
schema.encode('User', json.load(jer))
File "/home/bijesh/anaconda3/lib/python3.9/site-packages/asn1tools/compiler.py", line 137, in encode
type_.check_types(data)
File "/home/bijesh/anaconda3/lib/python3.9/site-packages/asn1tools/codecs/compiler.py", line 102, in check_types
return self.type_checker.encode(data)
File "/home/bijesh/anaconda3/lib/python3.9/site-packages/asn1tools/codecs/type_checker.py", line 311, in encode
raise e
File "/home/bijesh/anaconda3/lib/python3.9/site-packages/asn1tools/codecs/type_checker.py", line 307, in encode
self._type.encode(data)
File "/home/bijesh/anaconda3/lib/python3.9/site-packages/asn1tools/codecs/type_checker.py", line 142, in encode
self.encode_members(data)
File "/home/bijesh/anaconda3/lib/python3.9/site-packages/asn1tools/codecs/type_checker.py", line 154, in encode_members
raise e
File "/home/bijesh/anaconda3/lib/python3.9/site-packages/asn1tools/codecs/type_checker.py", line 150, in encode_members
member.encode(data[name])
File "/home/bijesh/anaconda3/lib/python3.9/site-packages/asn1tools/codecs/type_checker.py", line 224, in encode
raise EncodeError(
asn1tools.codecs.EncodeError: User.id: Expected data of type tuple(str, object), but got ['userName', 'johndoe'].
This script first
The important thing is to ensure that the object that you're trying to serialise in uPER is of the type expected by the compiled schema. You can't just poke any old object into the encoder and expect it to work. What this script shows is the object type that the encoder is expecting.
json.load(jer)is not producing an object of that type, which is why you're getting an error. That's why I'm focusing on whether youruser.jsonfile really is from an ASN.1 JER encoder, because it doesn't look like it is. It maybe perfectly valid JSON of itself, but it's not the style of JSON that JER defines. One option (see below, a fair way down) to have a script convert it to a JSON representation that the compiled schema can understand.BTW, relying on decoding from valid JER JSON, and re-encoding as uPER is the recommended way, in case your real scheme (is this an example?) has constraints in it. If you use the compiled schema to decode the JER JSON, the decoder should check and enforce the data against the constraints in the schema. Using json.load won't do that, meaning invalid data might slip through.
Script:
Gives me the following output:
and output.uper contains
Why is ASN1Tool's JSON Different to Your JSON?
Tidying up the first line of the output to compare the JSON generated by asn1tools with your json file:
The JER encoding for
idis very different in your JSON file:There are two possibilities for how JER can encode a CHOICE, depending on whether the schema has encoding instructions in it. From the standards doc Section 31, the difference is down to whether UNWRAPPED encoding is in force. Without UNWRAPPED, clause 31.3 applies:
Make of that what you can! Clause 31.2 is illuminating, because it talks about being able to omit
{and}, but does not refer to the use of[and]instead. The JER encoding rules have evolved since first considered; it's possible that, if your JER JSON data originates from elsewhere, they're using a previous version of the JER standard. I've not checked whether previous versions use[and].None the less, decoding your JSON file another way:
results in
Regardless, given that the only difference is whether the id's value is wrapped in square or curly braces, the simplest solution is likely to be to read the data from file, search / replace
[for{, same for the closing braces, and the,to a:, and then JER decode it and uPER encode itASN1 Playground
Using the ASN.1 Playground at asn.io, giving it the schema:
and the ASN1 value (in asn1 value notation)
produces the same uPER output:
So, my script and the ASN.1 playground are producing the same uPER output.