Skip to main content

Fast and efficient coding of binary data into non-breaking unicode whitespace

Project description

invisicode

Encodes arbitrary data into strings that display invisibly on devices and platforms supporting unicode.

Operates in base 4096 with one additional padding character for specific input widths, meaning 1.5 bytes per character on average.

Originally a coding scheme designed for Miza, as one of the methods to hide small amounts of persistent data in text messages to represent instructions for future edits to the message, while remaining visually undisruptive to users.

Capable of encoding both byte-strings and text-strings, and distinguishing between the two, using an additional signifier character (0x1d17a).

Demo

See https://thomas-xin.github.io/invisicode for an interactive demo of the encoding! You may use this to verify whether various examples of encoded text or data correctly render invisibly on your device or platform.

Installation

pip install invisicode

Usage

encode(b: str | bytes | bytearray | memoryview | numpy.ndarray) -> str
decode(s: str, expect: type = None) -> bytes | str

Examples

import invisicode
data = b"Hello World!"
encoded = invisicode.encode(data) # '\U000e0548\U000e06c6\U000e0f6c\U000e0206\U000e0f57\U000e0726\U000e046c\U000e0216'
assert invisicode.decode(encoded) == data # b"Hello World!"
import invisicode
data = "Hello World! ❤️"
encoded = invisicode.encode(data) # '\U0001d17a\U000e0548\U000e06c6\U000e0f6c\U000e0206\U000e0f57\U000e0726\U000e046c\U000e0216\U000e0420\U000e04ee\U000e0c8f\U000e003f'
assert invisicode.decode(encoded) == data # 'Hello World! ❤️'
import invisicode
import numpy as np
data = np.random.randint(0, 256, size=10 ** 8, dtype=np.uint8)
encoded = invisicode.encode(data) # '\U000e05b7\U000e0504\U000e02cc\U000e09a9\U000e0df5\U000e0066\U000e0d96󠅋\U000e0959\U000e0469...
len(data), len(encoded) # (100000000, 66666667)
assert invisicode.decode(encoded) == data.tobytes()
  • Invisicode exposes LEB128 encodings for strings, which is also internally used for slight coding efficiency improvements over UTF-8 (as we are reencoding the information anyway, the redundancy/error checking normally provided by UTF-8 is of no use to us).
import invisicode
invisicode.l128_encode("test") # b'test'
invisicode.l128_encode("Hello World! ❤️") # b'Hello World! \xe4N\x8f\xfc\x03'; 18 bytes vs 19 for utf-8
assert invisicode.l128_decode(invisicode.l128_encode("驈ꍬ啯ꍲᕤ")) == "驈ꍬ啯ꍲᕤ"

Protocol

  • Note: All numbers are encoded as little-endian bytes where applicable.

The encoding is performed as follows:

  • If the input is a string, encode it as leb128 representation (slightly more space-efficient than utf-8), and start with a string prefix character 0x1d17a (a non-printable character outside the normal invisicode range).
  • Each group of 3 bytes from the input is converted to two base-4096 numbers, by reinterpreting as a base-16777216 number and then splitting.
  • 0xE0000 is added to each resulting number, placing it in the Tags and selector and subsequent blocks, which will typically render as non-printable, non-breaking spaces.
  • If there is a single trailing byte (length % 3 == 1), it is encoded by itself by adding 0xE0000.
  • If there are two trailing bytes (length % 3 == 2), they are encoded similarly, but with a padding character 0xE0FFF appended at the end. This enables the string to still contain an odd amount of characters and stay within invisicode's normal range, while being distinct from the (length % 3 == 1) case.

The decoding is performed as follows:

  • If the string begins with the string prefix character (0x1d17a), remove that and flag the content as string.
  • If there are an odd number of characters, there are trailing bytes present. Attempt to detect the padding character to determine whether one or two bytes should be extracted.
  • 0xE0000 is subtracted from remaining characters; this step should raise an exception if any would go below 0.
  • The results are interpreted as base-16777216 numbers, split into three base-256 numbers each, and reinterpreted as bytes.
  • If necessary, convert the result back to a string.

Sample

The text between the characters "X" and "Y" below may be decoded as invisicode. It contains 2173 invisible characters, and represents 3258 bytes of leb128-data that may then be further decoded into 2568 unicode characters. For comparison, UTF-8 would encode the same text as 3635 bytes.

X𝅺󠕗󠦖󠉀󠙗󠸠󠛶󠌠󠻊󠀇󠜲󠉴󠘗󠝮󠙖󠍲󠈇󠫵󠁾󠲏󠀿󠂍󠰤󠽌󠿈󠀃󠝂󠁯󠛂󠙯󠙗󠴠󠻈󠰇󠂢󠽙󠝖󠤠󠺌󠐇󠺎󠀇󠚲󠽮󠝶󠴠󠺚󠀇󠝂󠕨󠈆󠕲󠛇󠍥󠈇󠶷󠁾󠄠󠛦󠁤󠜲󠁯󠙂󠁯󠒒󠄠󠺌󠸇󠂢󠁁󠙢󠱵󠛆󠔠󠹋󠀇󠘲󠵯󠛖󠑩󠛗󠹥󠝆󠂙󠜴󠜠󠚇󠑡󠈇󠥉󠐉󠁭󠝂󠥨󠛦󠥫󠛦󠁧󠫒󠟩󠈀󠙯󠋆󠤊󠛵󠁵󠾢󠟨󠲀󠟨󠮐󠁂󠝲󠕯󠛇󠹤󠝆󠤠󠻊󠀇󠙲󠑥󠈇󠪟󠁾󠐠󠚇󠍩󠈇󠉦󠛷󠁭󠘒󠥮󠈇󠑯󠚇󠉥󠈇󠕧󠞗󠘠󠺎󠼇󠹿󠜇󠺎󠰇󠹿󠐇󠼽󠼇󠹿󠸇󠂢󠤊󠈄󠣁󠁾󠨠󠝖󠑳󠈇󠅷󠛦󠅮󠈆󠳈󠁾󠣀󠁾󠐠󠙗󠱬󠈆󠦬󠁾󠤠󠛷󠁵󠲂󠟨󠈀󠽨󠝶󠤠󠦔󠵀󠈆󠕦󠙖󠥬󠛦󠁧󠠒󠟬󠋀󠜊󠛴󠑴󠘗󠤠󠺌󠀇󠛒󠭡󠙖󠔠󠺹󠀇󠞒󠕯󠈇󠣉󠁾󠔠󠛧󠕤󠜦󠑳󠘗󠑮󠩦󠩀󠂠󠕎󠝦󠉥󠈇󠻌󠈄󠽧󠛦󠅮󠈆󠪥󠁾󠜠󠚖󠕶󠈆󠞁󠁾󠤠󠛷󠁵󠲂󠟨󠈀󠁵󠈇󠲝󠋄󠸊󠙔󠕶󠜦󠰠󠓬󠜠󠛶󠹮󠘖󠔠󠺪󠀇󠛂󠑥󠈇󠣨󠁾󠂍󠺔󠟨󠣐󠝀󠺎󠴇󠐈󠣧󠁾󠳆󠁾󠦂󠁾󠤠󠛷󠁵󠲂󠟨󠈀󠽤󠝶󠁮󠡲󠱖󠂢󠕎󠝦󠉥󠈇󠶫󠁾󠜠󠛶󠹮󠘖󠔠󠺪󠀇󠜢󠹵󠈆󠟃󠁾󠦨󠁾󠄠󠜦󠕯󠛧󠁤󠼒󠟳󠭠󠟧󠭐󠟧󠈀󠹡󠙆󠐠󠙖󠕳󠜦󠁴󠪲󠟨󠈀󠽹󠝖󠠠󠺌󠸇󠂢󠕎󠝦󠉥󠈇󠷑󠁾󠻌󠈄󠽧󠛦󠅮󠈆󠪥󠁾󠴠󠘖󠕫󠈆󠮕󠁾󠤠󠛷󠁵󠬂󠟬󠲀󠟨󠈀󠉣󠞗󠴠󠻊󠰇󠂢󠕎󠝦󠉥󠈇󠳅󠁾󠻌󠈄󠽧󠛦󠅮󠈆󠪥󠁾󠌠󠘗󠁹󠫂󠟩󠈀󠽧󠛶󠉤󠞖󠁥󠲲󠟨󠋀󠸊󠙔󠕶󠜦󠰠󠓬󠜠󠛶󠹮󠘖󠤠󠺌󠀇󠝂󠱥󠛆󠌠󠺾󠀇󠘒󠰠󠚖󠁥󠩂󠟬󠈀󠹡󠙆󠠠󠝖󠑲󠈇󠊕󠁿󠤠󠛷󠁵󠲂󠟨󠋠󠨊󠕰󠥥󠐉󠕶󠈆󠹫󠛶󠹷󠈆󠞓󠁾󠔠󠘖󠡣󠈆󠑯󠚇󠉥󠈇󠽦󠜦󠌠󠛷󠰠󠛶󠝮󠈆󠫚󠁾󠤊󠛵󠉵󠈇󠣉󠁾󠠠󠙖󠉡󠝇󠂙󠜴󠈠󠙖󠹥󠈆󠍡󠚆󠹩󠙶󠀠󠻌󠨇󠐠󠑵󠈇󠛑󠁾󠤠󠛷󠥵󠐉󠕲󠈆󠽴󠛶󠌠󠚇󠁹󠥢󠟬󠪰󠟬󠬰󠟬󠈀󠽴󠈆󠅳󠞖󠌠󠺾󠀇󠚒󠹴󠂢󠹉󠜶󠑩󠙖󠀠󠺚󠀇󠝲󠁥󠘢󠑯󠚇󠬠󠛦󠝯󠈇󠊔󠁿󠜠󠚇󠑡󠦗󠍀󠈇󠕢󠙖󠁮󠙲󠥯󠛦󠁧󠺲󠟭󠰰󠟧󠾰󠟧󠪀󠟩󠈀󠹯󠈆󠪛󠁾󠨬󠕰󠁥󠚲󠽮󠝶󠐠󠼩󠀇󠝂󠕨󠈆󠅧󠛖󠁥󠫢󠟧󠈀󠹡󠙆󠜠󠙗󠂙󠜤󠁥󠙲󠹯󠛦󠁡󠩒󠟪󠈀󠱰󠘖󠁹󠩲󠟧󠫠󠟧󠈀󠑩󠋧󠨊󠐐󠹮󠛦󠹮󠙆󠤠󠙦󠤠󠛷󠁵󠲂󠟨󠈀󠍡󠚷󠼠󠻌󠀇󠛒󠁥󠚂󠝯󠈇󠥉󠐉󠁭󠙢󠕥󠛆󠹩󠙶󠄠󠻈󠰇󠂢󠽄󠛦󠂙󠝄󠐠󠙗󠱬󠈆󠯣󠁾󠴠󠙖󠤠󠛷󠥵󠐉󠕲󠈆󠽴󠛶󠈠󠛆󠹩󠙆󠠠󠻌󠀇󠝂󠁯󠜲󠕥󠩦󠩀󠂠󠕎󠝦󠉥󠈇󠶫󠁾󠜠󠛶󠹮󠘖󠤠󠺌󠀇󠙲󠙩󠙗󠤠󠺌󠀇󠞒󠕯󠈇󠣈󠁾󠔠󠜇󠴠󠓉󠨬󠓠󠙥󠙗󠁲󠳂󠁎󠙲󠹯󠛦󠁡󠩒󠟪󠈀󠕬󠝆󠘠󠻌󠀇󠞒󠕯󠈇󠣈󠁾󠐠󠛶󠹷󠈆󠚇󠋅󠸊󠙔󠕶󠜦󠔠󠻌󠀇󠙲󠹯󠛦󠁡󠩒󠟪󠈀󠕲󠛧󠌠󠹼󠀇󠘒󠽲󠝖󠑮󠈆󠪃󠁾󠄠󠛦󠁤󠙂󠍥󠙗󠑲󠈇󠟜󠁾󠤠󠛷󠁵󠲂󠟨󠋠󠸊󠙔󠕶󠜦󠔠󠻌󠀇󠙲󠹯󠛦󠁡󠩒󠟪󠈀󠅭󠚶󠁥󠥒󠟫󠈀󠽹󠝖󠤠󠺌󠀇󠘲󠥲󠈇󠲭󠁾󠦦󠁾󠨬󠓠󠙥󠙗󠁲󠱒󠟬󠈀󠽧󠛦󠅮󠈆󠣉󠁾󠌠󠘗󠁹󠸲󠟫󠈀󠽧󠛶󠉤󠞖󠁥󠲲󠟨󠋀󠸊󠙔󠕶󠜦󠬠󠻚󠀇󠙲󠹯󠛦󠁡󠲒󠟨󠈀󠕴󠛆󠁬󠫂󠟩󠈀󠁡󠛂󠕩󠈆󠲤󠁾󠄠󠛦󠁤󠚂󠉵󠝇󠔠󠼩󠀇󠞒󠕯󠈇󠣈󠁾󠨮󠂠󠕎󠝦󠉥󠈇󠻌󠈄󠽧󠛦󠅮󠈆󠣉󠁾󠜠󠚖󠕶󠈆󠞁󠁾󠤠󠛷󠁵󠲂󠟨󠈀󠁵󠈇󠲝󠋄󠸊󠙔󠕶󠜦󠔠󠻌󠀇󠙲󠹯󠛦󠁡󠲒󠟨󠈀󠕬󠝆󠘠󠻌󠀇󠞒󠕯󠈇󠣈󠁾󠐠󠛶󠹷󠈆󠚇󠋅󠸊󠙔󠕶󠜦󠰠󠓬󠜠󠛶󠹮󠘖󠔠󠺪󠀇󠜢󠹵󠈆󠟃󠁾󠟻󠁾󠂍󠰄󠽌󠿈󠀃󠘒󠽲󠝖󠑮󠈆󠪃󠁾󠄠󠛦󠁤󠙂󠍥󠙗󠑲󠈇󠢪󠁾󠤠󠛷󠁵󠲂󠟨󠋠󠸊󠙔󠕶󠜦󠰠󠓬󠜠󠛶󠹮󠘖󠔠󠺪󠀇󠛒󠭡󠙖󠠠󠺙󠀇󠞒󠕯󠈇󠣈󠁾󠌠󠜦󠁹󠫒󠟬󠋀󠸊󠙔󠕶󠜦󠄠󠻊󠔇󠻌󠀇󠙲󠹯󠛦󠁡󠩒󠟪󠈀󠅳󠞖󠄠󠺏󠼇󠹿󠰇󠺚󠠇󠻌󠀇󠙲󠽯󠙆󠥢󠙗󠬠󠺌󠰇󠂢󠕎󠝦󠉥󠈇󠻌󠈄󠽧󠛦󠅮󠈆󠣉󠁾󠶠󠈄󠕴󠛆󠁬󠸲󠟫󠴐󠟭󠈀󠁡󠛂󠕩󠈆󠲤󠁾󠄠󠛦󠁤󠚂󠉵󠝇󠔠󠼩󠀇󠞒󠕯󠈇󠣈󠁾󠨮󠂠󠥇󠝦󠁥󠲒󠟨󠈀󠽹󠝖󠠠󠺌󠀇󠝒󠁰󠦒󠟣󠡠󠹖󠈂󠥧󠝦󠁥󠠒󠟧󠈀󠽹󠝖󠤠󠺌󠬇󠹿󠀇󠝒󠁰󠧒󠹌󠂢󠥇󠝦󠁥󠢢󠅎󠹸󠀇󠞒󠕯󠈇󠚝󠁾󠣈󠁾󠔠󠜇󠘠󠕨󠀬󠙲󠙩󠙗󠄠󠹸󠀇󠞒󠕯󠈇󠣈󠁾󠔠󠜇󠴠󠓉󠨮󠓠󠙥󠙗󠁲󠱒󠟬󠾰󠟧󠣐󠁀󠓌󠲏󠀿󠜠󠛶󠹮󠘖󠔠󠺪󠀇󠙲󠙩󠙗󠤠󠺌󠨇󠓠󠙥󠙗󠁲󠳂󠩎󠻈󠀇󠙲󠹯󠛦󠁡󠩒󠟪󠈀󠥧󠝦󠁥󠲒󠟨󠋀󠜠󠚖󠕶󠈆󠞁󠁾󠤠󠛷󠁵󠲂󠟨󠈀󠁵󠈇󠚆󠋥󠸊󠙔󠕶󠜦󠰠󠓬󠜠󠛶󠹮󠘖󠔠󠺪󠀇󠙲󠙩󠙗󠤠󠺌󠨇󠓠󠙥󠙗󠁲󠱒󠟬󠮀󠟧󠈀󠽧󠛦󠅮󠈆󠪥󠁾󠜠󠚖󠕶󠈆󠣉󠁾󠀬󠙲󠙩󠙗󠄠󠹸󠀇󠞒󠕯󠈇󠣈󠁾󠔠󠜇󠴠󠓉󠨮󠂠󠕗󠦖󠙀󠙗󠬠󠛦󠝯󠛧󠌠󠹹󠐇󠓩󠔠󠘖󠡣󠈆󠑯󠚇󠉥󠈇󠽦󠜦󠌠󠛷󠰠󠛶󠝮󠈆󠫚󠁾󠤊󠛵󠉵󠈇󠣈󠁾󠠠󠙖󠉡󠝇󠂙󠜴󠈠󠙖󠹥󠈆󠍡󠚆󠹩󠙶󠬠󠻊󠐇󠻉󠨇󠐠󠑵󠈇󠛑󠁾󠤠󠛷󠥵󠐉󠕲󠈆󠽴󠛶󠌠󠚇󠁹󠢢󠟬󠈀󠽴󠈆󠅳󠞖󠌠󠺾󠀇󠚒󠹴󠂢󠹉󠜶󠑩󠙖󠀠󠺚󠀇󠝲󠁥󠘢󠑯󠚇󠬠󠛦󠝯󠈇󠊔󠁿󠜠󠚇󠑡󠦗󠍀󠈇󠕢󠙖󠁮󠙲󠥯󠛦󠁧󠲒󠟨󠿀󠟧󠈀󠹯󠈆󠪛󠁾󠨬󠕰󠁥󠚲󠽮󠝶󠐠󠼩󠀇󠝂󠕨󠈆󠅧󠛖󠁥󠬒󠟧󠈀󠹡󠙆󠜠󠙗󠂙󠜤󠁥󠙲󠹯󠛦󠁡󠩒󠟪󠈀󠱰󠘖󠁹󠫢󠟧󠈀󠑩󠋧󠨊󠒐󠄠󠺌󠀇󠚢󠍵󠝇󠜠󠘗󠹮󠘖󠠠󠻌󠀇󠝂󠱥󠛆󠌠󠺾󠀇󠞒󠕯󠈇󠣈󠁾󠠠󠛶󠁷󠒒󠂙󠛔󠘠󠙖󠱥󠚖󠝮󠈆󠲁󠁾󠨬󠑰󠑯󠝇󠁡󠪲󠟪󠣀󠱎󠹿󠀇󠛒󠭡󠙖󠠠󠺙󠀇󠞒󠕯󠈇󠲉󠁾󠣉󠁾󠣌󠁾󠔠󠛧󠕤󠜦󠑳󠘗󠑮󠩦󠩀󠂠󠕎󠝦󠉥󠈇󠳅󠁾󠜠󠛶󠹮󠘖󠔠󠺪󠀇󠙲󠙩󠙗󠄠󠹸󠀇󠞒󠕯󠈇󠣈󠁾󠔠󠜇󠴠󠓉󠨬󠓠󠙥󠙗󠁲󠪲󠟭󠨐󠟩󠈀󠽧󠛦󠅮󠈆󠪥󠁾󠰠󠙖󠁴󠱢󠟬󠈀󠽹󠝖󠠠󠺌󠀇󠙂󠝯󠛧󠜠󠕨󠨬󠓠󠙥󠙗󠁲󠱒󠟬󠈀󠽧󠛦󠅮󠈆󠪥󠁾󠈠󠝗󠁮󠰲󠟧󠈀󠉡󠛷󠹵󠙆󠌠󠺨󠀇󠘒󠑮󠈆󠕤󠜶󠉥󠝇󠨠󠺊󠀇󠞒󠕯󠈇󠣈󠁾󠟽󠁾󠨮󠓠󠙥󠙗󠁲󠨒󠟬󠱐󠟬󠈀󠽧󠛦󠅮󠈆󠪥󠁾󠴠󠘖󠕫󠈆󠦘󠁾󠤠󠛷󠁵󠫢󠟬󠲀󠟨󠿠󠟧󠧐󠟲󠈀󠉣󠞗󠈠󠻈󠰇󠂢󠕎󠝦󠉥󠈇󠳅󠁾󠜠󠛶󠹮󠘖󠐠󠻊󠔇󠺪󠀇󠜲󠥡󠈇󠯣󠁾󠻓󠥄󠟲󠈀󠽧󠛶󠉤󠞖󠁥󠲲󠟨󠋀󠸊󠙔󠕶󠜦󠔠󠻌󠀇󠙲󠹯󠛦󠁡󠩒󠟪󠈀󠕴󠛆󠁬󠸲󠟫󠈀󠁡󠛂󠕩󠈆󠊥󠁿󠛳󠁾󠣡󠁾󠄠󠛦󠁤󠚂󠉵󠝇󠔠󠼩󠀇󠞒󠕯󠈇󠣈󠁾󠨮󠂠󠕎󠝦󠉥󠈇󠶫󠁾󠲥󠁾󠜠󠛶󠹮󠘖󠔠󠺪󠀇󠙲󠙩󠙗󠄠󠹸󠀇󠞒󠕯󠈇󠣈󠁾󠔠󠜇󠴠󠓉󠨬󠓠󠙥󠙗󠁲󠩂󠟬󠳀󠁎󠙲󠹯󠛦󠁡󠲒󠟨󠈀󠕬󠝆󠬠󠺎󠀇󠞒󠕯󠈇󠣈󠁾󠐠󠛶󠹷󠈆󠚇󠋅󠸊󠙔󠕶󠜦󠬠󠻚󠀇󠙲󠹯󠛦󠁡󠲒󠟨󠈀󠕲󠛧󠌠󠹼󠀇󠘒󠽲󠝖󠑮󠈆󠏱󠁿󠞶󠁾󠞵󠁾󠄠󠛦󠁤󠙂󠍥󠙗󠑲󠈇󠢪󠁾󠤠󠛷󠁵󠲒󠟨󠋠󠸊󠙔󠕶󠜦󠔠󠻌󠀇󠙲󠹯󠛦󠁡󠩒󠟪󠈀󠅭󠚶󠁥󠦂󠟩󠈀󠽹󠝖󠠠󠺌󠴇󠹿󠀇󠘲󠥲󠈇󠲭󠁾󠨬󠓠󠙥󠙗󠁲󠪲󠟭󠈀󠽧󠛦󠅮󠈆󠪥󠁾󠌠󠘗󠁹󠫂󠟩󠈀󠽧󠛶󠉤󠞖󠁥󠲲󠟨󠋀󠸊󠙔󠕶󠜦󠔠󠻌󠀇󠙲󠹯󠛦󠁡󠩒󠟪󠈀󠕴󠛆󠁬󠸲󠟫󠈀󠁡󠛂󠕩󠈆󠲤󠁾󠄠󠛦󠁤󠚂󠉵󠝇󠔠󠼩󠀇󠞒󠕯󠈇󠣈󠁾󠨮󠂠󠕎󠝦󠉥󠈇󠻌󠈄󠽧󠛦󠅮󠈆󠪥󠁾󠜠󠚖󠕶󠈆󠞁󠁾󠤠󠛷󠁵󠲂󠟨󠈀󠁵󠈇󠲝󠋄󠸊󠙔󠕶󠜦󠰠󠓬󠪚󠁾󠜠󠛶󠹮󠘖󠔠󠺪󠀇󠛂󠑥󠈇󠳆󠁾󠤠󠛷󠁵󠲂󠟨󠈀󠽤󠝶󠁮󠡲󠱖󠂢󠕎󠝦󠉥󠈇󠳅󠁾󠜠󠛶󠹮󠘖󠔠󠺪󠀇󠜢󠹵󠈆󠟃󠁾󠄠󠜦󠕯󠛧󠁤󠠲󠟪󠈀󠹡󠙆󠐠󠙖󠕳󠜦󠁴󠪲󠟨󠈀󠽹󠝖󠠠󠺌󠸇󠂢󠕎󠝦󠉥󠈇󠻌󠈄󠽧󠛦󠅮󠈆󠣉󠁾󠴠󠘖󠕫󠈆󠮕󠁾󠤠󠛷󠁵󠲒󠟨󠈀󠉣󠞗󠔠󠻊󠴇󠻊󠰇󠂢󠕎󠝦󠉥󠈇󠻌󠈄󠽧󠛦󠅮󠈆󠪥󠁾󠌠󠘗󠁹󠸲󠟫󠈀󠽧󠛶󠉤󠞖󠁥󠲲󠟨󠋀󠸊󠙔󠕶󠜦󠔠󠻌󠰇󠓬󠜠󠛶󠹮󠘖󠔠󠺪󠀇󠝂󠱥󠛆󠰠󠺚󠀇󠘒󠰠󠚖󠁥󠩂󠟬󠈀󠹡󠙆󠠠󠝖󠑲󠈇󠊕󠁿󠤠󠛷󠁵󠲒󠟨󠋠Y

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

invisicode-1.1.0.tar.gz (16.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

invisicode-1.1.0-py3-none-any.whl (8.4 kB view details)

Uploaded Python 3

File details

Details for the file invisicode-1.1.0.tar.gz.

File metadata

  • Download URL: invisicode-1.1.0.tar.gz
  • Upload date:
  • Size: 16.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.13.8

File hashes

Hashes for invisicode-1.1.0.tar.gz
Algorithm Hash digest
SHA256 85261a13bbfa51fa414073f7d72e58e5bc0d937ee3acacae4ff1b1441034fd64
MD5 c488f5485e97403121e06925a4c877f0
BLAKE2b-256 b7eeb075a9f9c14f3c29b0c42813df023fb26a6ed1706ad026eacfc22f706764

See more details on using hashes here.

File details

Details for the file invisicode-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: invisicode-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.13.8

File hashes

Hashes for invisicode-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ccabed859ce880d21ef1f1c5a37c3f2b3fc3f8a2295336ad4ad26a11092bc65a
MD5 f4ef8023aa8cf8f03e579c8253b4251b
BLAKE2b-256 70b2c0cc4136607080a3decd3df9e7c8c1aad61319357b43bb2bd41af05eb4a5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page