{"id":17216227,"url":"https://github.com/exhuma/x690","last_synced_at":"2025-03-25T13:42:52.304Z","repository":{"id":62589764,"uuid":"279778337","full_name":"exhuma/x690","owner":"exhuma","description":null,"archived":false,"fork":false,"pushed_at":"2022-09-30T05:14:52.000Z","size":551,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-02T05:33:50.260Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/exhuma.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-15T05:56:31.000Z","updated_at":"2021-10-06T06:24:09.000Z","dependencies_parsed_at":"2022-11-03T17:01:44.437Z","dependency_job_id":null,"html_url":"https://github.com/exhuma/x690","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exhuma%2Fx690","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exhuma%2Fx690/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exhuma%2Fx690/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exhuma%2Fx690/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/exhuma","download_url":"https://codeload.github.com/exhuma/x690/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245473518,"owners_count":20621249,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-15T03:27:13.860Z","updated_at":"2025-03-25T13:42:52.282Z","avatar_url":"https://github.com/exhuma.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Pure Python `X.690`_ implementation\n===================================\n\n.. image:: https://github.com/exhuma/x690/workflows/Testing/badge.svg?branch=main\n    :alt: Code Style\n\n.. image:: https://github.com/exhuma/x690/workflows/Build%20\u0026%20Publish%20Docs/badge.svg?branch=main\n    :alt: Build \u0026 Publish Docs\n\n.. _X.690: https://www.itu.int/rec/recommendation.asp?lang=en\u0026parent=T-REC-X.690-201508-I\n\n\nThis module contains a pure Python implementation of the \"x690\" standard for\nBER encoding/decoding. Other encodings are currently unsupported but\npull-requests are welcome.\n\n\nSupporting New Types\n--------------------\n\nSome applications may need to support types which are not defined in the X.690\nstandard. This is supported by this library but the types must be defined and\nregistered.\n\nTo register a type, simply subclass ``x690.types.Type``. This will take care of\nthe registration. Make sure that your new type is imported before using it.\n\nNew types should define the following 3 class-variables:\n\n**TYPECLASS**\n    A value from ``x690.util.TypeClass``\n**NATURE**\n    A value from ``x690.util.TypeNature``\n**TAG**\n    A numerical identifier for the type\n\nRefer to the x690 standard for more details on these values. As a general\nrule-of-thumb you can assume that the class is either \"context\" or\n\"application\" (it might be good to keep the \"universal\" class reserved for\nx690). The nature should be \"primitive\" for simple values and \"constructed\" for\ncomposed types. The tag is free to choose as long as you don't overlap with an\nexisting type.\n\nTo convert raw-bytes into a Python object, override ``x690.Type.decode_raw``\nand conversely also ``x690.Type.encode_raw``. Refer to the docstrings for more\ndetails.\n\n\nReverse Engineering Bytes\n-------------------------\n\nAll types defined in the ``x690`` library provide a ``.pretty()`` method which\nreturns a prettyfied string.\n\nIf you are confronted with a bytes-object encoded using X.690 but don't have\nany documentation, you can write the following loop::\n\n    from x690 import decode\n\n    data = open(\"mydatafile.bin\", \"rb\").read()\n\n    value, nxt = decode(data)\n    print(value.pretty())\n\n    while nxt \u003c len(data):\n        value, nxt = decode(data, nxt)\n        print(value.pretty())\n\nThis should get you started.\n\nIf the data contain non-standard types, they will get detected as \"UnknownType\"\nand will print out the type-class, nature and tag in the pretty-printed block.\n\nThis will allow you to define your own subclass of ``x690.types.Type`` using\nthose values. Override ``decode(...)`` in that class to handle the unknown\ntype.\n\n\nExamples\n========\n\nEncoding to bytes\n-----------------\n\nEncoding to bytes can be done by simply calling the Python builting ``bytes()``\non instances from ``x690.types``:\n\nEncoding of a single value\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code:: python\n\n    \u003e\u003e\u003e import x690.types as t\n    \u003e\u003e\u003e myvalue = t.Integer(12)\n    \u003e\u003e\u003e asbytes = bytes(myvalue)\n    \u003e\u003e\u003e repr(asbytes)\n    b'\\x02\\x01\\x0c'\n\nEncoding of a composite value using Sequence\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code:: python\n\n    \u003e\u003e\u003e import x690.types as t\n    \u003e\u003e\u003e myvalue = t.Sequence(\n    ...     t.Integer(12),\n    ...     t.Integer(12),\n    ...     t.Integer(12),\n    ... )\n    \u003e\u003e\u003e asbytes = bytes(myvalue)\n    \u003e\u003e\u003e repr(asbytes)\n    b'0\\t\\x02\\x01\\x0c\\x02\\x01\\x0c\\x02\\x01\\x0c'\n\n\nDecoding from bytes\n~~~~~~~~~~~~~~~~~~~\n\nDecode bytes by calling ``x690.types.decode`` on your byte data. This will\nreturn a tuple where the first value contains the decoded object, and the\nsecond one will contain any remaining bytes which were not decoded.\n\n.. code:: python\n\n    \u003e\u003e\u003e import x690\n    \u003e\u003e\u003e data = b'0\\t\\x02\\x01\\x0c\\x02\\x01\\x0c\\x02\\x01\\x0c'\n    \u003e\u003e\u003e decoded, nxt = x690.decode(data)\n    \u003e\u003e\u003e decoded\n    Sequence(Integer(12), Integer(12), Integer(12))\n    \u003e\u003e\u003e nxt\n    11\n\n\nType-Hinting \u0026 Enforcing\n~~~~~~~~~~~~~~~~~~~~~~~~\n\n**New in 0.3.0**\n\nWhen decoding bytes, it is possible to specify an expcted type which does two\nthings: Firstly, it tells tools like ``mypy`` what the return type will be and\nsecondly, it runs an internal type-check which *ensures* that the returned\nvalue is of the expected type. ``x690.exc.UnexpectedType`` is raised otherwise.\n\nThis does of course only work if you know the type in advance.\n\n.. code:: python\n\n    \u003e\u003e\u003e import x690\n    \u003e\u003e\u003e import x690.types as t\n    \u003e\u003e\u003e data = b'0\\t\\x02\\x01\\x0c\\x02\\x01\\x0c\\x02\\x01\\x0c'\n    \u003e\u003e\u003e decoded, nxt = x690.decode(data, enforce_type=t.Sequence)\n    \u003e\u003e\u003e decoded\n    Sequence(Integer(12), Integer(12), Integer(12))\n    \u003e\u003e\u003e nxt\n    11\n\n\nStrict Decoding\n~~~~~~~~~~~~~~~\n\n**New in 0.3.0**\n\nWhen decoding using ``decode`` and you don't expect any remaining bytes, use\n``strict=True`` which will raise ``x690.exc.IncompleteDecoding`` if there's any\nremaining data.\n\n.. code:: python\n\n    \u003e\u003e\u003e import x690\n    \u003e\u003e\u003e data = b'0\\t\\x02\\x01\\x0c\\x02\\x01\\x0c\\x02\\x01\\x0cjunk-bytes'\n    \u003e\u003e\u003e decoded, nxt = x690.decode(data, strict=True)\n    Traceback (most recent call last):\n      ...\n    x690.exc.IncompleteDecoding: Strict decoding still had 10 remaining bytes!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexhuma%2Fx690","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexhuma%2Fx690","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexhuma%2Fx690/lists"}