TapHome

Byte encodings and checksums

TapHome script functions TOBASE64 and FROMBASE64 (also base64url), TOHEX and FROMHEX, CRC16 and CRC32 — bytes as text and back, and checksums of frames.

TOBASE64, FROMBASE64, TOHEX, FROMHEX, CRC16 and CRC32 turn bytes into text and back and compute checksums, usually together with the encryption and hash functions. They only build values, so they work in every script. All of them need Core 2026.1 on TapHome Next, build 40991 or newer (not yet in the official release).

TOBASE64, TOHEX, CRC16 and CRC32 take byte data like the encryption functions: a collection<uint8>, a blob or a string, used as ISO-8859-1 bytes (for UTF-8 pass TOBYTES(text, "utf-8")). TOBASE64 and TOHEX return a string, CRC16 and CRC32 a uint number; FROMBASE64 and FROMHEX take text and return a collection<uint8>.

TOBASE64, FROMBASE64

TOBASE64 turns byte data into Base64 text, FROMBASE64 turns Base64 text back into bytes.

1
2
TOBASE64(data [, variant])
FROMBASE64(text [, variant])

variant is "standard" (the default) or "url", not case sensitive. "url" is base64url (RFC 4648 §5), which uses - and _ instead of + and /. TOBASE64 with "url" leaves out the = padding, as JWT and most web APIs expect (Python base64.urlsafe_b64encode(data).rstrip(b"=")); FROMBASE64 with "url" accepts text with or without the padding.

Returns — TOBASE64 a string, FROMBASE64 a collection<uint8>.

Remarks — ENCODE and DECODE with "base64" go through UTF-8 text, so bytes above 0x7F do not survive them. Encrypted and other binary data goes through TOBASE64 and FROMBASE64.

Example

TOBASE64(FROMHEX("fbff"));
# Result: "+/8="
TOBASE64(FROMHEX("fbff"), "url");
# Result: "-_8"
TOHEX(FROMBASE64("-_8", "url"));
# Result: "fbff"

Errors — TOBASE64 Unknown variant. Valid values are ‘standard’, ‘url’ (FROMBASE64 names itself); FROMBASE64 - ‘+’ and ‘/’ are not base64url characters, leave the “url” argument out for standard Base64; FROMBASE64 - argument must be a string; The provided text does not have the base64 format.

Available — Core 2026.1 on TapHome Next, build 40991 or newer (not yet in the official release).

TOHEX, FROMHEX

TOHEX returns byte data as lower-case hexadecimal text, FROMHEX turns hexadecimal text back into bytes.

1
2
TOHEX(data)
FROMHEX(text)

Remarks

  • FROMHEX accepts upper- and lower-case digits and whitespace between them, as Python’s bytes.fromhex. Any other character, including a 0x prefix or : separators, is an error, and so is an odd number of digits. An empty string gives an empty collection.
  • Unlike BYTECOLLECTION from hexadecimal text, which silently ignores other characters and is limited to 2048 bytes, FROMHEX has no length limit, so it takes back anything TOHEX produced.

Example

TOBASE64(FROMHEX("ff0080"));
# Result: "/wCA"
TOHEX(FROMBASE64("/wCA"));
# Result: "ff0080"
TOHEX(FROMHEX("FF 00 80"));
# Result: "ff0080"

Errors — FROMHEX - invalid hex digit ‘x’ (remove a prefix or separators with REPLACE); FROMHEX - the number of hex digits must be even, it is N; FROMHEX - argument must be a string.

Available — Core 2026.1 on TapHome Next, build 40991 or newer (not yet in the official release).

CRC16, CRC32

CRC16 returns the 16-bit CRC checksum of byte data, CRC32 the CRC-32 of zlib, Ethernet and ZIP (Python zlib.crc32).

1
2
CRC16(data [, variant])
CRC32(data)

variant selects the parameters of CRC16, not case sensitive. The check value is the CRC of the text "123456789":

variantCheck valueAlso known as
"MODBUS" (default)0x4B37Modbus RTU frames
"XMODEM"0x31C3Python binascii.crc_hqx(data, 0)
"CCITT-FALSE"0x29B1"IBM-3740" is accepted as the same variant
"KERMIT"0x2189

The check value of CRC32 is 0xCBF43926 (3421780262).

Returns — a uint number, not bytes. To put the checksum into a frame, pack it with PACKVALUE in the byte order the protocol expects; Modbus RTU sends the low byte first.

Example

TOSTRING(CRC16(FROMHEX("0103000A0001")), "X4");
# Result: "08A4"
TOSTRING(CRC32("123456789"), "X8");
# Result: "CBF43926"

Example — append a Modbus RTU checksum

VAR frame := FROMHEX("01 03 00 0A 00 01");
VAR crc := BYTECOLLECTION(2);
PACKVALUE(crc, 0, LittleEndianUint16, CRC16(frame));
APPEND(frame, crc);
# Result: frame is 01 03 00 0A 00 01 A4 08

Errors — CRC16 Unknown variant. Valid values are ‘MODBUS’, ‘XMODEM’, ‘CCITT-FALSE’, ‘KERMIT’.

Available — Core 2026.1 on TapHome Next, build 40991 or newer (not yet in the official release).

See also — Encryption and hashes, Binary data, Data type conversions.