From 007cc0b97b265f140bec8773ce5692d297a42f0a Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Tue, 28 Oct 2025 17:02:04 -0400 Subject: [PATCH] Define IETF RFC 4648 schemas Signed-off-by: Juan Cruz Viotti --- README.markdown | 1 + schemas/ietf/encoding/base16.json | 20 + schemas/ietf/encoding/base32.json | 18 + schemas/ietf/encoding/base32hex.json | 18 + schemas/ietf/encoding/base64.json | 18 + schemas/ietf/encoding/base64url.json | 18 + test/ietf/encoding/base16.test.json | 501 +++++++++++++++++++++++ test/ietf/encoding/base32.test.json | 491 ++++++++++++++++++++++ test/ietf/encoding/base32hex.test.json | 511 +++++++++++++++++++++++ test/ietf/encoding/base64.test.json | 526 ++++++++++++++++++++++++ test/ietf/encoding/base64url.test.json | 541 +++++++++++++++++++++++++ 11 files changed, 2663 insertions(+) create mode 100644 schemas/ietf/encoding/base16.json create mode 100644 schemas/ietf/encoding/base32.json create mode 100644 schemas/ietf/encoding/base32hex.json create mode 100644 schemas/ietf/encoding/base64.json create mode 100644 schemas/ietf/encoding/base64url.json create mode 100644 test/ietf/encoding/base16.test.json create mode 100644 test/ietf/encoding/base32.test.json create mode 100644 test/ietf/encoding/base32hex.test.json create mode 100644 test/ietf/encoding/base64.test.json create mode 100644 test/ietf/encoding/base64url.test.json diff --git a/README.markdown b/README.markdown index 01e97c5..324024f 100644 --- a/README.markdown +++ b/README.markdown @@ -53,6 +53,7 @@ expressed as JSON Schema definitions. | IEEE | [IEEE Std 754-2019](https://ieeexplore.ieee.org/document/8766229) | IEEE Standard for Floating-Point Arithmetic | | IEEE | [IEEE Std 1003.1-2017](https://pubs.opengroup.org/onlinepubs/9699919799/) | IEEE Standard for Information Technology—Portable Operating System Interface (POSIX) Base Specifications, Issue 7 | | IETF | [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986) | Uniform Resource Identifier (URI): Generic Syntax | +| IETF | [RFC 4648](https://www.rfc-editor.org/rfc/rfc4648) | The Base16, Base32, and Base64 Data Encodings | | IETF | [RFC 4918](https://www.rfc-editor.org/rfc/rfc4918) | HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) | | IETF | [RFC 5322](https://www.rfc-editor.org/rfc/rfc5322) | Internet Message Format | | IETF | [RFC 5646](https://www.rfc-editor.org/rfc/rfc5646) | Tags for Identifying Languages (BCP 47) | diff --git a/schemas/ietf/encoding/base16.json b/schemas/ietf/encoding/base16.json new file mode 100644 index 0000000..0b78118 --- /dev/null +++ b/schemas/ietf/encoding/base16.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "RFC 4648 Base16 Encoding", + "description": "Uses digits 0-9 and letters A-F (case-insensitive). Each byte encodes to exactly 2 characters, no padding required", + "examples": [ + "48656C6C6F20576F726C6421", + "DEADBEEF", + "0FB7", + "666F6F626172", + "" + ], + "x-license": "https://github.com/sourcemeta/std/blob/main/LICENSE", + "x-links": [ "https://www.rfc-editor.org/rfc/rfc4648.html#section-8" ], + "type": "string", + "not": { + "pattern": "[\\x00-\\x1F]" + }, + "pattern": "^([0-9A-Fa-f]{2})*$", + "contentEncoding": "base16" +} diff --git a/schemas/ietf/encoding/base32.json b/schemas/ietf/encoding/base32.json new file mode 100644 index 0000000..bebf88f --- /dev/null +++ b/schemas/ietf/encoding/base32.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "RFC 4648 Base32 Encoding", + "description": "Uses uppercase letters A-Z and digits 2-7 (32 characters total). Padding with = to multiple of 8 characters", + "examples": [ + "JBSWY3DPEBLW64TMMQ======", + "MFRGG===", + "MZXW6===", + "MZXW6YQ=", + "MZXW6YTB", + "" + ], + "x-license": "https://github.com/sourcemeta/std/blob/main/LICENSE", + "x-links": [ "https://www.rfc-editor.org/rfc/rfc4648.html#section-6" ], + "type": "string", + "pattern": "^([A-Z2-7]{8})*([A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}=)?$", + "contentEncoding": "base32" +} diff --git a/schemas/ietf/encoding/base32hex.json b/schemas/ietf/encoding/base32hex.json new file mode 100644 index 0000000..85c996c --- /dev/null +++ b/schemas/ietf/encoding/base32hex.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "RFC 4648 Base32hex Encoding", + "description": "Uses digits 0-9 and uppercase letters A-V (32 characters total). Padding with = to multiple of 8 characters", + "examples": [ + "91IMOR3F41BMUSJCCG======", + "C5H66===", + "CPNMU===", + "CPNMUO8=", + "CPNMUOJ1", + "" + ], + "x-license": "https://github.com/sourcemeta/std/blob/main/LICENSE", + "x-links": [ "https://www.rfc-editor.org/rfc/rfc4648.html#section-7" ], + "type": "string", + "pattern": "^([0-9A-V]{8})*([0-9A-V]{2}={6}|[0-9A-V]{4}={4}|[0-9A-V]{5}={3}|[0-9A-V]{7}=)?$", + "contentEncoding": "base32hex" +} diff --git a/schemas/ietf/encoding/base64.json b/schemas/ietf/encoding/base64.json new file mode 100644 index 0000000..e988363 --- /dev/null +++ b/schemas/ietf/encoding/base64.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "RFC 4648 Base64 Encoding", + "description": "Uses uppercase letters A-Z, lowercase letters a-z, digits 0-9, plus sign (+), and forward slash (/), with equals sign (=) used for padding", + "examples": [ + "R0lGODlhAQABAAAAACw=", + "SGVsbG8gV29ybGQh", + "YQ==", + "YWI=", + "YWJj", + "" + ], + "x-license": "https://github.com/sourcemeta/std/blob/main/LICENSE", + "x-links": [ "https://www.rfc-editor.org/rfc/rfc4648.html#section-4" ], + "type": "string", + "pattern": "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", + "contentEncoding": "base64" +} diff --git a/schemas/ietf/encoding/base64url.json b/schemas/ietf/encoding/base64url.json new file mode 100644 index 0000000..3d1ca14 --- /dev/null +++ b/schemas/ietf/encoding/base64url.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "RFC 4648 Base64url Encoding", + "description": "Base64 encoding with URL and filename safe alphabet as defined in RFC 4648 section 5. Uses hyphen (-) and underscore (_) instead of plus (+) and slash (/)", + "examples": [ + "R0lGODlhAQABAAAAACw=", + "SGVsbG8gV29ybGQh", + "YQ==", + "YWI=", + "YWJj", + "" + ], + "x-license": "https://github.com/sourcemeta/std/blob/main/LICENSE", + "x-links": [ "https://www.rfc-editor.org/rfc/rfc4648.html#section-5" ], + "type": "string", + "pattern": "^([A-Za-z0-9_-]{4})*([A-Za-z0-9_-]{2}==|[A-Za-z0-9_-]{3}=)?$", + "contentEncoding": "base64url" +} diff --git a/test/ietf/encoding/base16.test.json b/test/ietf/encoding/base16.test.json new file mode 100644 index 0000000..eb43979 --- /dev/null +++ b/test/ietf/encoding/base16.test.json @@ -0,0 +1,501 @@ +{ + "x-license": "https://github.com/sourcemeta/std/blob/main/LICENSE", + "target": "../../../schemas/ietf/encoding/base16.json", + "tests": [ + { + "description": "Valid - empty string", + "data": "", + "valid": true + }, + { + "description": "Valid - single byte uppercase", + "data": "0F", + "valid": true + }, + { + "description": "Valid - single byte lowercase", + "data": "0f", + "valid": true + }, + { + "description": "Valid - single byte mixed case", + "data": "0F", + "valid": true + }, + { + "description": "Valid - 'Hello World!' in hex", + "data": "48656C6C6F20576F726C6421", + "valid": true + }, + { + "description": "Valid - 'foo' in hex", + "data": "666F6F", + "valid": true + }, + { + "description": "Valid - all uppercase", + "data": "DEADBEEF", + "valid": true + }, + { + "description": "Valid - all lowercase", + "data": "deadbeef", + "valid": true + }, + { + "description": "Valid - mixed case", + "data": "DeAdBeEf", + "valid": true + }, + { + "description": "Valid - all zeros", + "data": "0000", + "valid": true + }, + { + "description": "Valid - all F's uppercase", + "data": "FFFF", + "valid": true + }, + { + "description": "Valid - all f's lowercase", + "data": "ffff", + "valid": true + }, + { + "description": "Valid - only digits 0-9", + "data": "0123456789", + "valid": true + }, + { + "description": "Valid - only letters A-F uppercase", + "data": "ABCDEF", + "valid": true + }, + { + "description": "Valid - only letters a-f lowercase", + "data": "abcdef", + "valid": true + }, + { + "description": "Valid - two bytes", + "data": "0FB7", + "valid": true + }, + { + "description": "Valid - four bytes", + "data": "DEADBEEF", + "valid": true + }, + { + "description": "Valid - eight bytes", + "data": "0123456789ABCDEF", + "valid": true + }, + { + "description": "Valid - sixteen bytes", + "data": "0123456789ABCDEF0123456789ABCDEF", + "valid": true + }, + { + "description": "Valid - long hex string", + "data": "48656C6C6F20576F726C64212048657265206973206120766572792076657279206C6F6E672068657820737472696E67", + "valid": true + }, + { + "description": "Invalid - single character (odd length)", + "data": "0", + "valid": false + }, + { + "description": "Invalid - three characters (odd length)", + "data": "ABC", + "valid": false + }, + { + "description": "Invalid - five characters (odd length)", + "data": "ABCDE", + "valid": false + }, + { + "description": "Invalid - seven characters (odd length)", + "data": "ABCDEFG", + "valid": false + }, + { + "description": "Invalid - contains G", + "data": "0G", + "valid": false + }, + { + "description": "Invalid - contains H", + "data": "0H", + "valid": false + }, + { + "description": "Invalid - contains Z", + "data": "0Z", + "valid": false + }, + { + "description": "Invalid - contains g", + "data": "0g", + "valid": false + }, + { + "description": "Invalid - contains h", + "data": "0h", + "valid": false + }, + { + "description": "Invalid - contains z", + "data": "0z", + "valid": false + }, + { + "description": "Invalid - contains space", + "data": "DE AD", + "valid": false + }, + { + "description": "Invalid - contains hyphen", + "data": "DE-AD", + "valid": false + }, + { + "description": "Invalid - contains underscore", + "data": "DE_AD", + "valid": false + }, + { + "description": "Invalid - contains plus", + "data": "DE+AD", + "valid": false + }, + { + "description": "Invalid - contains slash", + "data": "DE/AD", + "valid": false + }, + { + "description": "Invalid - contains period", + "data": "DE.AD", + "valid": false + }, + { + "description": "Invalid - contains comma", + "data": "DE,AD", + "valid": false + }, + { + "description": "Invalid - contains colon", + "data": "DE:AD", + "valid": false + }, + { + "description": "Invalid - contains semicolon", + "data": "DE;AD", + "valid": false + }, + { + "description": "Invalid - contains (", + "data": "DE(AD", + "valid": false + }, + { + "description": "Invalid - contains )", + "data": "DE)AD", + "valid": false + }, + { + "description": "Invalid - contains [", + "data": "DE[AD", + "valid": false + }, + { + "description": "Invalid - contains ]", + "data": "DE]AD", + "valid": false + }, + { + "description": "Invalid - contains {", + "data": "DE{AD", + "valid": false + }, + { + "description": "Invalid - contains }", + "data": "DE}AD", + "valid": false + }, + { + "description": "Invalid - contains !", + "data": "DE!AD", + "valid": false + }, + { + "description": "Invalid - contains ?", + "data": "DE?AD", + "valid": false + }, + { + "description": "Invalid - contains @", + "data": "DE@AD", + "valid": false + }, + { + "description": "Invalid - contains #", + "data": "DE#AD", + "valid": false + }, + { + "description": "Invalid - contains $", + "data": "DE$AD", + "valid": false + }, + { + "description": "Invalid - contains %", + "data": "DE%AD", + "valid": false + }, + { + "description": "Invalid - contains ^", + "data": "DE^AD", + "valid": false + }, + { + "description": "Invalid - contains &", + "data": "DE&AD", + "valid": false + }, + { + "description": "Invalid - contains *", + "data": "DE*AD", + "valid": false + }, + { + "description": "Invalid - contains ~", + "data": "DE~AD", + "valid": false + }, + { + "description": "Invalid - contains `", + "data": "DE`AD", + "valid": false + }, + { + "description": "Invalid - contains |", + "data": "DE|AD", + "valid": false + }, + { + "description": "Invalid - contains \\", + "data": "DE\\AD", + "valid": false + }, + { + "description": "Invalid - contains '", + "data": "DE'AD", + "valid": false + }, + { + "description": "Invalid - contains \"", + "data": "DE\"AD", + "valid": false + }, + { + "description": "Invalid - contains <", + "data": "DE", + "data": "DE>AD", + "valid": false + }, + { + "description": "Invalid - leading space", + "data": " DEAD", + "valid": false + }, + { + "description": "Invalid - trailing space", + "data": "DEAD ", + "valid": false + }, + { + "description": "Invalid - leading tab", + "data": "\tDEAD", + "valid": false + }, + { + "description": "Invalid - trailing tab", + "data": "DEAD\t", + "valid": false + }, + { + "description": "Invalid - tab in middle", + "data": "DE\tAD", + "valid": false + }, + { + "description": "Invalid - contains newline", + "data": "DE\nAD", + "valid": false + }, + { + "description": "Invalid - contains carriage return", + "data": "DE\rAD", + "valid": false + }, + { + "description": "Invalid - non-ASCII character", + "data": "DEéAD", + "valid": false + }, + { + "description": "Invalid - emoji", + "data": "DE😀AD", + "valid": false + }, + { + "description": "Invalid - number type", + "data": 123, + "valid": false + }, + { + "description": "Invalid - boolean type", + "data": true, + "valid": false + }, + { + "description": "Invalid - null type", + "data": null, + "valid": false + }, + { + "description": "Valid - digit 0", + "data": "00", + "valid": true + }, + { + "description": "Valid - digit 1", + "data": "11", + "valid": true + }, + { + "description": "Valid - digit 2", + "data": "22", + "valid": true + }, + { + "description": "Valid - digit 3", + "data": "33", + "valid": true + }, + { + "description": "Valid - digit 4", + "data": "44", + "valid": true + }, + { + "description": "Valid - digit 5", + "data": "55", + "valid": true + }, + { + "description": "Valid - digit 6", + "data": "66", + "valid": true + }, + { + "description": "Valid - digit 7", + "data": "77", + "valid": true + }, + { + "description": "Valid - digit 8", + "data": "88", + "valid": true + }, + { + "description": "Valid - digit 9", + "data": "99", + "valid": true + }, + { + "description": "Valid - letter A uppercase", + "data": "AA", + "valid": true + }, + { + "description": "Valid - letter B uppercase", + "data": "BB", + "valid": true + }, + { + "description": "Valid - letter C uppercase", + "data": "CC", + "valid": true + }, + { + "description": "Valid - letter D uppercase", + "data": "DD", + "valid": true + }, + { + "description": "Valid - letter E uppercase", + "data": "EE", + "valid": true + }, + { + "description": "Valid - letter F uppercase", + "data": "FF", + "valid": true + }, + { + "description": "Valid - letter a lowercase", + "data": "aa", + "valid": true + }, + { + "description": "Valid - letter b lowercase", + "data": "bb", + "valid": true + }, + { + "description": "Valid - letter c lowercase", + "data": "cc", + "valid": true + }, + { + "description": "Valid - letter d lowercase", + "data": "dd", + "valid": true + }, + { + "description": "Valid - letter e lowercase", + "data": "ee", + "valid": true + }, + { + "description": "Valid - letter f lowercase", + "data": "ff", + "valid": true + }, + { + "description": "Valid - repeating pattern", + "data": "0F0F0F0F", + "valid": true + }, + { + "description": "Valid - alternating case", + "data": "AaBbCcDd", + "valid": true + }, + { + "description": "Valid - all digits and letters mixed", + "data": "0123456789ABCDEFabcdef", + "valid": true + } + ] +} diff --git a/test/ietf/encoding/base32.test.json b/test/ietf/encoding/base32.test.json new file mode 100644 index 0000000..eeed8b7 --- /dev/null +++ b/test/ietf/encoding/base32.test.json @@ -0,0 +1,491 @@ +{ + "x-license": "https://github.com/sourcemeta/std/blob/main/LICENSE", + "target": "../../../schemas/ietf/encoding/base32.json", + "tests": [ + { + "description": "Valid - empty string", + "data": "", + "valid": true + }, + { + "description": "Valid - single byte (2 chars + 6 padding)", + "data": "ME======", + "valid": true + }, + { + "description": "Valid - two bytes (4 chars + 4 padding)", + "data": "MZXQ====", + "valid": true + }, + { + "description": "Valid - three bytes (5 chars + 3 padding)", + "data": "MZXW6===", + "valid": true + }, + { + "description": "Valid - four bytes (7 chars + 1 padding)", + "data": "MZXW6YQ=", + "valid": true + }, + { + "description": "Valid - five bytes (8 chars, no padding)", + "data": "MZXW6YTB", + "valid": true + }, + { + "description": "Valid - 'Hello World!'", + "data": "JBSWY3DPEBLW64TMMQ======", + "valid": true + }, + { + "description": "Valid - 'foo'", + "data": "MZXW6===", + "valid": true + }, + { + "description": "Valid - 'foobar'", + "data": "MZXW6YTBOI======", + "valid": true + }, + { + "description": "Valid - all A's", + "data": "AAAAAAAA", + "valid": true + }, + { + "description": "Valid - all 7's", + "data": "77777777", + "valid": true + }, + { + "description": "Valid - mixed alphabet", + "data": "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", + "valid": true + }, + { + "description": "Valid - only letters A-Z", + "data": "ABCDEFGHIJKLMNOP", + "valid": true + }, + { + "description": "Valid - only digits 2-7", + "data": "23456723", + "valid": true + }, + { + "description": "Valid - 16 chars no padding", + "data": "ABCDEFGHIJKLMNOP", + "valid": true + }, + { + "description": "Valid - 24 chars no padding", + "data": "ABCDEFGHIJKLMNOPQRSTUVWX", + "valid": true + }, + { + "description": "Valid - long string with padding", + "data": "JBSWY3DPEBLW64TMMQQQ====", + "valid": true + }, + { + "description": "Invalid - single char without padding", + "data": "M", + "valid": false + }, + { + "description": "Invalid - two chars without padding", + "data": "ME", + "valid": false + }, + { + "description": "Invalid - three chars without padding", + "data": "MEZ", + "valid": false + }, + { + "description": "Invalid - four chars without padding", + "data": "MZXQ", + "valid": false + }, + { + "description": "Invalid - five chars without padding", + "data": "MZXW6", + "valid": false + }, + { + "description": "Invalid - six chars without padding", + "data": "MZXW6Y", + "valid": false + }, + { + "description": "Invalid - seven chars without padding", + "data": "MZXW6YQ", + "valid": false + }, + { + "description": "Invalid - nine chars without padding", + "data": "MZXW6YTBO", + "valid": false + }, + { + "description": "Invalid - contains 0 (not in base32 alphabet)", + "data": "M0======", + "valid": false + }, + { + "description": "Invalid - contains 1 (not in base32 alphabet)", + "data": "M1======", + "valid": false + }, + { + "description": "Invalid - contains 8 (not in base32 alphabet)", + "data": "M8======", + "valid": false + }, + { + "description": "Invalid - contains 9 (not in base32 alphabet)", + "data": "M9======", + "valid": false + }, + { + "description": "Invalid - lowercase letters", + "data": "mzxw6===", + "valid": false + }, + { + "description": "Invalid - mixed case", + "data": "MzXw6===", + "valid": false + }, + { + "description": "Valid - 7 chars + 1 padding (non-canonical but syntactically valid)", + "data": "MZXW6YT=", + "valid": true + }, + { + "description": "Invalid - wrong padding count (2 equals)", + "data": "MZXW6Y==", + "valid": false + }, + { + "description": "Invalid - wrong padding count (5 equals)", + "data": "MZX=====", + "valid": false + }, + { + "description": "Invalid - wrong padding count (7 equals)", + "data": "M=======", + "valid": false + }, + { + "description": "Invalid - too much padding (8 equals)", + "data": "========", + "valid": false + }, + { + "description": "Invalid - padding in middle", + "data": "ME======MZXW6===", + "valid": false + }, + { + "description": "Invalid - padding not at end", + "data": "M=ZXQAAA", + "valid": false + }, + { + "description": "Invalid - contains space", + "data": "MZXW 6===", + "valid": false + }, + { + "description": "Invalid - contains hyphen", + "data": "MZXW-6===", + "valid": false + }, + { + "description": "Invalid - contains underscore", + "data": "MZXW_6===", + "valid": false + }, + { + "description": "Invalid - contains plus", + "data": "MZXW+6===", + "valid": false + }, + { + "description": "Invalid - contains slash", + "data": "MZXW/6===", + "valid": false + }, + { + "description": "Invalid - contains period", + "data": "MZXW.6===", + "valid": false + }, + { + "description": "Invalid - contains comma", + "data": "MZXW,6===", + "valid": false + }, + { + "description": "Invalid - contains (", + "data": "MZXW(===", + "valid": false + }, + { + "description": "Invalid - contains )", + "data": "MZXW)===", + "valid": false + }, + { + "description": "Invalid - contains [", + "data": "MZXW[===", + "valid": false + }, + { + "description": "Invalid - contains ]", + "data": "MZXW]===", + "valid": false + }, + { + "description": "Invalid - contains {", + "data": "MZXW{===", + "valid": false + }, + { + "description": "Invalid - contains }", + "data": "MZXW}===", + "valid": false + }, + { + "description": "Invalid - contains !", + "data": "MZXW!===", + "valid": false + }, + { + "description": "Invalid - contains ?", + "data": "MZXW?===", + "valid": false + }, + { + "description": "Invalid - contains @", + "data": "MZXW@===", + "valid": false + }, + { + "description": "Invalid - contains #", + "data": "MZXW#===", + "valid": false + }, + { + "description": "Invalid - contains $", + "data": "MZXW$===", + "valid": false + }, + { + "description": "Invalid - contains %", + "data": "MZXW%===", + "valid": false + }, + { + "description": "Invalid - contains ^", + "data": "MZXW^===", + "valid": false + }, + { + "description": "Invalid - contains &", + "data": "MZXW&===", + "valid": false + }, + { + "description": "Invalid - contains *", + "data": "MZXW*===", + "valid": false + }, + { + "description": "Invalid - contains ~", + "data": "MZXW~===", + "valid": false + }, + { + "description": "Invalid - contains `", + "data": "MZXW`===", + "valid": false + }, + { + "description": "Invalid - contains |", + "data": "MZXW|===", + "valid": false + }, + { + "description": "Invalid - contains \\", + "data": "MZXW\\===", + "valid": false + }, + { + "description": "Invalid - contains :", + "data": "MZXW:===", + "valid": false + }, + { + "description": "Invalid - contains ;", + "data": "MZXW;===", + "valid": false + }, + { + "description": "Invalid - contains '", + "data": "MZXW'===", + "valid": false + }, + { + "description": "Invalid - contains \"", + "data": "MZXW\"===", + "valid": false + }, + { + "description": "Invalid - contains <", + "data": "MZXW<===", + "valid": false + }, + { + "description": "Invalid - contains >", + "data": "MZXW>===", + "valid": false + }, + { + "description": "Invalid - leading space", + "data": " MZXW6===", + "valid": false + }, + { + "description": "Invalid - trailing space", + "data": "MZXW6=== ", + "valid": false + }, + { + "description": "Invalid - leading tab", + "data": "\tMZXW6===", + "valid": false + }, + { + "description": "Invalid - trailing tab", + "data": "MZXW6===\t", + "valid": false + }, + { + "description": "Invalid - tab in middle", + "data": "MZXW\t6===", + "valid": false + }, + { + "description": "Invalid - contains newline", + "data": "MZXW\n6===", + "valid": false + }, + { + "description": "Invalid - contains carriage return", + "data": "MZXW\r6===", + "valid": false + }, + { + "description": "Invalid - non-ASCII character", + "data": "MZXWé===", + "valid": false + }, + { + "description": "Invalid - emoji", + "data": "MZXW😀===", + "valid": false + }, + { + "description": "Invalid - number type", + "data": 123, + "valid": false + }, + { + "description": "Invalid - boolean type", + "data": true, + "valid": false + }, + { + "description": "Invalid - null type", + "data": null, + "valid": false + }, + { + "description": "Invalid - padding at beginning", + "data": "======ME", + "valid": false + }, + { + "description": "Invalid - only padding", + "data": "========", + "valid": false + }, + { + "description": "Invalid - mixed padding", + "data": "M=Z=W===", + "valid": false + }, + { + "description": "Valid - all alphabet chars at start", + "data": "ABCDEFGH", + "valid": true + }, + { + "description": "Valid - all alphabet chars at end", + "data": "STUVWXYZ", + "valid": true + }, + { + "description": "Valid - digit 2", + "data": "2AAAAAAA", + "valid": true + }, + { + "description": "Valid - digit 3", + "data": "3AAAAAAA", + "valid": true + }, + { + "description": "Valid - digit 4", + "data": "4AAAAAAA", + "valid": true + }, + { + "description": "Valid - digit 5", + "data": "5AAAAAAA", + "valid": true + }, + { + "description": "Valid - digit 6", + "data": "6AAAAAAA", + "valid": true + }, + { + "description": "Valid - digit 7", + "data": "7AAAAAAA", + "valid": true + }, + { + "description": "Valid - repeating pattern", + "data": "ABABABABABABABAB", + "valid": true + }, + { + "description": "Valid - very long valid base32", + "data": "JBSWY3DPFQQFO33SNRSCC===", + "valid": true + }, + { + "description": "Invalid - 3 chars with 4 padding (should be 6 padding for 2 chars)", + "data": "MEZ====", + "valid": false + }, + { + "description": "Invalid - 6 chars with 3 padding (no valid padding for 6 chars)", + "data": "MZXW6Y===", + "valid": false + } + ] +} diff --git a/test/ietf/encoding/base32hex.test.json b/test/ietf/encoding/base32hex.test.json new file mode 100644 index 0000000..e539397 --- /dev/null +++ b/test/ietf/encoding/base32hex.test.json @@ -0,0 +1,511 @@ +{ + "x-license": "https://github.com/sourcemeta/std/blob/main/LICENSE", + "target": "../../../schemas/ietf/encoding/base32hex.json", + "tests": [ + { + "description": "Valid - empty string", + "data": "", + "valid": true + }, + { + "description": "Valid - single byte (2 chars + 6 padding)", + "data": "C4======", + "valid": true + }, + { + "description": "Valid - two bytes (4 chars + 4 padding)", + "data": "CPNG====", + "valid": true + }, + { + "description": "Valid - three bytes (5 chars + 3 padding)", + "data": "CPNMU===", + "valid": true + }, + { + "description": "Valid - four bytes (7 chars + 1 padding)", + "data": "CPNMUO8=", + "valid": true + }, + { + "description": "Valid - five bytes (8 chars, no padding)", + "data": "CPNMUOJ1", + "valid": true + }, + { + "description": "Valid - 'Hello World!'", + "data": "91IMOR3F41BMUSJCCG======", + "valid": true + }, + { + "description": "Valid - 'foo'", + "data": "CPNMU===", + "valid": true + }, + { + "description": "Valid - 'foobar'", + "data": "CPNMUOJ1E8======", + "valid": true + }, + { + "description": "Valid - all 0's", + "data": "00000000", + "valid": true + }, + { + "description": "Valid - all V's", + "data": "VVVVVVVV", + "valid": true + }, + { + "description": "Valid - mixed alphabet", + "data": "0123456789ABCDEFGHIJKLMNOPQRSTUV", + "valid": true + }, + { + "description": "Valid - only digits 0-9", + "data": "01234567", + "valid": true + }, + { + "description": "Valid - only letters A-V", + "data": "ABCDEFGHIJKLMNOP", + "valid": true + }, + { + "description": "Valid - 16 chars no padding", + "data": "0123456789ABCDEF", + "valid": true + }, + { + "description": "Valid - 24 chars no padding", + "data": "0123456789ABCDEFGHIJKLMN", + "valid": true + }, + { + "description": "Valid - long string with padding", + "data": "91IMOR3F41BMUSJCCGGG====", + "valid": true + }, + { + "description": "Invalid - single char without padding", + "data": "C", + "valid": false + }, + { + "description": "Invalid - two chars without padding", + "data": "C4", + "valid": false + }, + { + "description": "Invalid - three chars without padding", + "data": "C4P", + "valid": false + }, + { + "description": "Invalid - four chars without padding", + "data": "CPNG", + "valid": false + }, + { + "description": "Invalid - five chars without padding", + "data": "CPNMU", + "valid": false + }, + { + "description": "Invalid - six chars without padding", + "data": "CPNMUO", + "valid": false + }, + { + "description": "Invalid - seven chars without padding", + "data": "CPNMUO8", + "valid": false + }, + { + "description": "Invalid - nine chars without padding", + "data": "CPNMUOJ1E", + "valid": false + }, + { + "description": "Invalid - contains W (not in base32hex alphabet)", + "data": "CPNMUW==", + "valid": false + }, + { + "description": "Invalid - contains X (not in base32hex alphabet)", + "data": "CPNMUX==", + "valid": false + }, + { + "description": "Invalid - contains Y (not in base32hex alphabet)", + "data": "CPNMUY==", + "valid": false + }, + { + "description": "Invalid - contains Z (not in base32hex alphabet)", + "data": "CPNMUZ==", + "valid": false + }, + { + "description": "Invalid - lowercase letters", + "data": "cpnmu===", + "valid": false + }, + { + "description": "Invalid - mixed case", + "data": "CpNmU===", + "valid": false + }, + { + "description": "Valid - 7 chars + 1 padding (non-canonical but syntactically valid)", + "data": "CPNMUOJ=", + "valid": true + }, + { + "description": "Invalid - wrong padding count (2 equals)", + "data": "CPNMUO==", + "valid": false + }, + { + "description": "Invalid - wrong padding count (5 equals)", + "data": "CPN=====", + "valid": false + }, + { + "description": "Invalid - wrong padding count (7 equals)", + "data": "C=======", + "valid": false + }, + { + "description": "Invalid - too much padding (8 equals)", + "data": "========", + "valid": false + }, + { + "description": "Invalid - padding in middle", + "data": "C4======CPNMU===", + "valid": false + }, + { + "description": "Invalid - padding not at end", + "data": "C=PNG000", + "valid": false + }, + { + "description": "Invalid - contains space", + "data": "CPNMU ===", + "valid": false + }, + { + "description": "Invalid - contains hyphen", + "data": "CPNMU-===", + "valid": false + }, + { + "description": "Invalid - contains underscore", + "data": "CPNMU_===", + "valid": false + }, + { + "description": "Invalid - contains plus", + "data": "CPNMU+===", + "valid": false + }, + { + "description": "Invalid - contains slash", + "data": "CPNMU/===", + "valid": false + }, + { + "description": "Invalid - contains period", + "data": "CPNMU.===", + "valid": false + }, + { + "description": "Invalid - contains comma", + "data": "CPNMU,===", + "valid": false + }, + { + "description": "Invalid - contains (", + "data": "CPNMU(==", + "valid": false + }, + { + "description": "Invalid - contains )", + "data": "CPNMU)==", + "valid": false + }, + { + "description": "Invalid - contains [", + "data": "CPNMU[==", + "valid": false + }, + { + "description": "Invalid - contains ]", + "data": "CPNMU]==", + "valid": false + }, + { + "description": "Invalid - contains {", + "data": "CPNMU{==", + "valid": false + }, + { + "description": "Invalid - contains }", + "data": "CPNMU}==", + "valid": false + }, + { + "description": "Invalid - contains !", + "data": "CPNMU!==", + "valid": false + }, + { + "description": "Invalid - contains ?", + "data": "CPNMU?==", + "valid": false + }, + { + "description": "Invalid - contains @", + "data": "CPNMU@==", + "valid": false + }, + { + "description": "Invalid - contains #", + "data": "CPNMU#==", + "valid": false + }, + { + "description": "Invalid - contains $", + "data": "CPNMU$==", + "valid": false + }, + { + "description": "Invalid - contains %", + "data": "CPNMU%==", + "valid": false + }, + { + "description": "Invalid - contains ^", + "data": "CPNMU^==", + "valid": false + }, + { + "description": "Invalid - contains &", + "data": "CPNMU&==", + "valid": false + }, + { + "description": "Invalid - contains *", + "data": "CPNMU*==", + "valid": false + }, + { + "description": "Invalid - contains ~", + "data": "CPNMU~==", + "valid": false + }, + { + "description": "Invalid - contains `", + "data": "CPNMU`==", + "valid": false + }, + { + "description": "Invalid - contains |", + "data": "CPNMU|==", + "valid": false + }, + { + "description": "Invalid - contains \\", + "data": "CPNMU\\==", + "valid": false + }, + { + "description": "Invalid - contains :", + "data": "CPNMU:==", + "valid": false + }, + { + "description": "Invalid - contains ;", + "data": "CPNMU;==", + "valid": false + }, + { + "description": "Invalid - contains '", + "data": "CPNMU'==", + "valid": false + }, + { + "description": "Invalid - contains \"", + "data": "CPNMU\"==", + "valid": false + }, + { + "description": "Invalid - contains <", + "data": "CPNMU<==", + "valid": false + }, + { + "description": "Invalid - contains >", + "data": "CPNMU>==", + "valid": false + }, + { + "description": "Invalid - leading space", + "data": " CPNMU===", + "valid": false + }, + { + "description": "Invalid - trailing space", + "data": "CPNMU=== ", + "valid": false + }, + { + "description": "Invalid - leading tab", + "data": "\tCPNMU===", + "valid": false + }, + { + "description": "Invalid - trailing tab", + "data": "CPNMU===\t", + "valid": false + }, + { + "description": "Invalid - tab in middle", + "data": "CPN\tMU===", + "valid": false + }, + { + "description": "Invalid - contains newline", + "data": "CPN\nMU===", + "valid": false + }, + { + "description": "Invalid - contains carriage return", + "data": "CPN\rMU===", + "valid": false + }, + { + "description": "Invalid - non-ASCII character", + "data": "CPNMUé==", + "valid": false + }, + { + "description": "Invalid - emoji", + "data": "CPNMU😀==", + "valid": false + }, + { + "description": "Invalid - number type", + "data": 123, + "valid": false + }, + { + "description": "Invalid - boolean type", + "data": true, + "valid": false + }, + { + "description": "Invalid - null type", + "data": null, + "valid": false + }, + { + "description": "Invalid - padding at beginning", + "data": "======C4", + "valid": false + }, + { + "description": "Invalid - only padding", + "data": "========", + "valid": false + }, + { + "description": "Invalid - mixed padding", + "data": "C=P=MU==", + "valid": false + }, + { + "description": "Valid - digit 0", + "data": "00000000", + "valid": true + }, + { + "description": "Valid - digit 1", + "data": "11111111", + "valid": true + }, + { + "description": "Valid - digit 2", + "data": "22222222", + "valid": true + }, + { + "description": "Valid - digit 3", + "data": "33333333", + "valid": true + }, + { + "description": "Valid - digit 4", + "data": "44444444", + "valid": true + }, + { + "description": "Valid - digit 5", + "data": "55555555", + "valid": true + }, + { + "description": "Valid - digit 6", + "data": "66666666", + "valid": true + }, + { + "description": "Valid - digit 7", + "data": "77777777", + "valid": true + }, + { + "description": "Valid - digit 8", + "data": "88888888", + "valid": true + }, + { + "description": "Valid - digit 9", + "data": "99999999", + "valid": true + }, + { + "description": "Valid - letter A", + "data": "AAAAAAAA", + "valid": true + }, + { + "description": "Valid - letter V", + "data": "VVVVVVVV", + "valid": true + }, + { + "description": "Valid - repeating pattern", + "data": "0A0A0A0A", + "valid": true + }, + { + "description": "Valid - very long valid base32hex", + "data": "91IMOR3F5GG5E33IDHIA====", + "valid": true + }, + { + "description": "Invalid - 3 chars with 4 padding (should be 6 padding for 2 chars)", + "data": "C4P====", + "valid": false + }, + { + "description": "Invalid - 6 chars with 3 padding (no valid padding for 6 chars)", + "data": "CPNMUO===", + "valid": false + } + ] +} diff --git a/test/ietf/encoding/base64.test.json b/test/ietf/encoding/base64.test.json new file mode 100644 index 0000000..e36d75f --- /dev/null +++ b/test/ietf/encoding/base64.test.json @@ -0,0 +1,526 @@ +{ + "x-license": "https://github.com/sourcemeta/std/blob/main/LICENSE", + "target": "../../../schemas/ietf/encoding/base64.json", + "tests": [ + { + "description": "Valid - empty string", + "data": "", + "valid": true + }, + { + "description": "Valid - single char with padding", + "data": "YQ==", + "valid": true + }, + { + "description": "Valid - two chars with padding", + "data": "YWI=", + "valid": true + }, + { + "description": "Valid - three chars no padding", + "data": "YWJj", + "valid": true + }, + { + "description": "Valid - four chars", + "data": "YWJjZA==", + "valid": true + }, + { + "description": "Valid - Hello World", + "data": "SGVsbG8gV29ybGQh", + "valid": true + }, + { + "description": "Invalid - insufficient chars in final group", + "data": "a+b/c==", + "valid": false + }, + { + "description": "Valid - with plus sign", + "data": "a+b/cg==", + "valid": true + }, + { + "description": "Valid - with slash", + "data": "abc/def=", + "valid": true + }, + { + "description": "Valid - all uppercase", + "data": "QUJDRA==", + "valid": true + }, + { + "description": "Valid - all lowercase", + "data": "cXdlcg==", + "valid": true + }, + { + "description": "Valid - all digits", + "data": "MTIzNDU2Nzg5MA==", + "valid": true + }, + { + "description": "Valid - GIF header", + "data": "R0lGODlhAQABAAAAACw=", + "valid": true + }, + { + "description": "Valid - multiple of 4 chars", + "data": "YWJjZGVmZ2hpamtsbW5vcA==", + "valid": true + }, + { + "description": "Valid - long string", + "data": "VGhpcyBpcyBhIGxvbmcgYmFzZTY0IGVuY29kZWQgc3RyaW5nIHRoYXQgc2hvdWxkIGJlIHZhbGlk", + "valid": true + }, + { + "description": "Invalid - one equals padding only", + "data": "YWI==", + "valid": false + }, + { + "description": "Invalid - three equals", + "data": "YQ===", + "valid": false + }, + { + "description": "Invalid - padding in middle", + "data": "YQ==YWI=", + "valid": false + }, + { + "description": "Invalid - padding not at end", + "data": "Y=WI", + "valid": false + }, + { + "description": "Invalid - single character without padding (insufficient data)", + "data": "Y", + "valid": false + }, + { + "description": "Invalid - two characters without required padding", + "data": "YW", + "valid": false + }, + { + "description": "Invalid - three characters without required padding", + "data": "YWJ", + "valid": false + }, + { + "description": "Invalid - contains space", + "data": "YWJj ZA==", + "valid": false + }, + { + "description": "Invalid - contains dash", + "data": "YWJj-ZA==", + "valid": false + }, + { + "description": "Invalid - contains underscore", + "data": "YWJj_ZA==", + "valid": false + }, + { + "description": "Invalid - contains period", + "data": "YWJj.ZA==", + "valid": false + }, + { + "description": "Invalid - contains comma", + "data": "YWJj,ZA==", + "valid": false + }, + { + "description": "Invalid - contains special char", + "data": "YWJj@ZA==", + "valid": false + }, + { + "description": "Invalid - number type", + "data": 123, + "valid": false + }, + { + "description": "Invalid - boolean type", + "data": true, + "valid": false + }, + { + "description": "Invalid - null type", + "data": null, + "valid": false + }, + { + "description": "Valid - only uppercase letters", + "data": "ABCDEFGH", + "valid": true + }, + { + "description": "Valid - only lowercase letters", + "data": "abcdefgh", + "valid": true + }, + { + "description": "Valid - only digits", + "data": "01234567", + "valid": true + }, + { + "description": "Valid - plus at start", + "data": "+ABC", + "valid": true + }, + { + "description": "Valid - slash at start", + "data": "/ABC", + "valid": true + }, + { + "description": "Valid - plus at end", + "data": "ABC+", + "valid": true + }, + { + "description": "Valid - slash at end", + "data": "ABC/", + "valid": true + }, + { + "description": "Valid - multiple plus signs", + "data": "A+B+C+D+", + "valid": true + }, + { + "description": "Valid - multiple slashes", + "data": "A/B/C/D/", + "valid": true + }, + { + "description": "Valid - plus and slash mixed", + "data": "A+B/C+D/", + "valid": true + }, + { + "description": "Valid - 8 chars no padding", + "data": "ABCDEFGH", + "valid": true + }, + { + "description": "Valid - 12 chars no padding", + "data": "ABCDEFGHIJKL", + "valid": true + }, + { + "description": "Valid - 16 chars no padding", + "data": "ABCDEFGHIJKLMNOP", + "valid": true + }, + { + "description": "Invalid - 5 chars without required padding", + "data": "ABCDE", + "valid": false + }, + { + "description": "Invalid - 6 chars without required padding", + "data": "ABCDEF", + "valid": false + }, + { + "description": "Invalid - 7 chars without required padding", + "data": "ABCDEFG", + "valid": false + }, + { + "description": "Invalid - 10 chars without required padding", + "data": "ABCDEFGHIJ", + "valid": false + }, + { + "description": "Valid - padding with two equals at end of 4-char group", + "data": "AB==", + "valid": true + }, + { + "description": "Valid - padding with one equal at end of 4-char group", + "data": "ABC=", + "valid": true + }, + { + "description": "Valid - 8 chars then padding", + "data": "ABCDEFGH/w==", + "valid": true + }, + { + "description": "Valid - all char types", + "data": "AZ09+/AB", + "valid": true + }, + { + "description": "Valid - repeated patterns", + "data": "AAAABBBBCCCCDDDD", + "valid": true + }, + { + "description": "Valid - zeros encoded", + "data": "AAAA", + "valid": true + }, + { + "description": "Valid - max values encoded", + "data": "////", + "valid": true + }, + { + "description": "Valid - alternating chars", + "data": "AaAaAaAa", + "valid": true + }, + { + "description": "Invalid - padding at beginning", + "data": "==ABCD", + "valid": false + }, + { + "description": "Invalid - padding in first position", + "data": "=ABC", + "valid": false + }, + { + "description": "Invalid - only equals", + "data": "====", + "valid": false + }, + { + "description": "Invalid - single equals", + "data": "=", + "valid": false + }, + { + "description": "Invalid - double equals alone", + "data": "==", + "valid": false + }, + { + "description": "Invalid - four equals", + "data": "ABCD====", + "valid": false + }, + { + "description": "Invalid - padding then more chars", + "data": "AB==CD", + "valid": false + }, + { + "description": "Invalid - padding then padding", + "data": "AB===", + "valid": false + }, + { + "description": "Invalid - mixed padding positions", + "data": "A=B=", + "valid": false + }, + { + "description": "Invalid - three chars with two equals", + "data": "ABC==", + "valid": false + }, + { + "description": "Invalid - two chars with one equal", + "data": "AB=", + "valid": false + }, + { + "description": "Invalid - five chars with padding", + "data": "ABCDE=", + "valid": false + }, + { + "description": "Valid - uppercase G", + "data": "ABCG", + "valid": true + }, + { + "description": "Valid - lowercase g", + "data": "ABCg", + "valid": true + }, + { + "description": "Invalid - contains (", + "data": "ABC(", + "valid": false + }, + { + "description": "Invalid - contains )", + "data": "ABC)", + "valid": false + }, + { + "description": "Invalid - contains [", + "data": "ABC[", + "valid": false + }, + { + "description": "Invalid - contains ]", + "data": "ABC]", + "valid": false + }, + { + "description": "Invalid - contains {", + "data": "ABC{", + "valid": false + }, + { + "description": "Invalid - contains }", + "data": "ABC}", + "valid": false + }, + { + "description": "Invalid - contains !", + "data": "ABC!", + "valid": false + }, + { + "description": "Invalid - contains ?", + "data": "ABC?", + "valid": false + }, + { + "description": "Invalid - contains *", + "data": "ABC*", + "valid": false + }, + { + "description": "Invalid - contains &", + "data": "ABC&", + "valid": false + }, + { + "description": "Invalid - contains $", + "data": "ABC$", + "valid": false + }, + { + "description": "Invalid - contains %", + "data": "ABC%", + "valid": false + }, + { + "description": "Invalid - contains #", + "data": "ABC#", + "valid": false + }, + { + "description": "Invalid - contains ^", + "data": "ABC^", + "valid": false + }, + { + "description": "Invalid - contains ~", + "data": "ABC~", + "valid": false + }, + { + "description": "Invalid - contains `", + "data": "ABC`", + "valid": false + }, + { + "description": "Invalid - contains |", + "data": "ABC|", + "valid": false + }, + { + "description": "Invalid - contains \\", + "data": "ABC\\", + "valid": false + }, + { + "description": "Invalid - contains ;", + "data": "ABC;", + "valid": false + }, + { + "description": "Invalid - contains :", + "data": "ABC:", + "valid": false + }, + { + "description": "Invalid - contains '", + "data": "ABC'", + "valid": false + }, + { + "description": "Invalid - contains \"", + "data": "ABC\"", + "valid": false + }, + { + "description": "Invalid - contains <", + "data": "ABC<", + "valid": false + }, + { + "description": "Invalid - contains >", + "data": "ABC>", + "valid": false + }, + { + "description": "Invalid - leading tab", + "data": "\tABCD", + "valid": false + }, + { + "description": "Invalid - trailing tab", + "data": "ABCD\t", + "valid": false + }, + { + "description": "Invalid - tab in middle", + "data": "AB\tCD", + "valid": false + }, + { + "description": "Invalid - leading space", + "data": " ABCD", + "valid": false + }, + { + "description": "Invalid - trailing space", + "data": "ABCD ", + "valid": false + }, + { + "description": "Invalid - multiple spaces", + "data": "AB CD", + "valid": false + }, + { + "description": "Invalid - contains carriage return", + "data": "AB\rCD", + "valid": false + }, + { + "description": "Invalid - non-ASCII character", + "data": "ABCé", + "valid": false + }, + { + "description": "Invalid - emoji", + "data": "ABC😀", + "valid": false + }, + { + "description": "Valid - very long valid base64", + "data": "VGhpcyBpcyBhIHZlcnkgbG9uZyBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdGhhdCB3ZSBhcmUgdXNpbmcgdG8gdGVzdCB0aGUgdmFsaWRhdGlvbiBvZiBsb25nZXIgaW5wdXRzIHRvIG1ha2Ugc3VyZSBvdXIgcGF0dGVybiB3b3JrcyBjb3JyZWN0bHk=", + "valid": true + } + ] +} diff --git a/test/ietf/encoding/base64url.test.json b/test/ietf/encoding/base64url.test.json new file mode 100644 index 0000000..8bd4878 --- /dev/null +++ b/test/ietf/encoding/base64url.test.json @@ -0,0 +1,541 @@ +{ + "x-license": "https://github.com/sourcemeta/std/blob/main/LICENSE", + "target": "../../../schemas/ietf/encoding/base64url.json", + "tests": [ + { + "description": "Valid - empty string", + "data": "", + "valid": true + }, + { + "description": "Valid - single char with padding", + "data": "YQ==", + "valid": true + }, + { + "description": "Valid - two chars with padding", + "data": "YWI=", + "valid": true + }, + { + "description": "Valid - three chars no padding", + "data": "YWJj", + "valid": true + }, + { + "description": "Valid - four chars", + "data": "YWJjZA==", + "valid": true + }, + { + "description": "Valid - Hello World", + "data": "SGVsbG8gV29ybGQh", + "valid": true + }, + { + "description": "Invalid - insufficient chars in final group", + "data": "a-b_c==", + "valid": false + }, + { + "description": "Valid - with hyphen", + "data": "a-b_cg==", + "valid": true + }, + { + "description": "Valid - with underscore", + "data": "abc_def=", + "valid": true + }, + { + "description": "Valid - all uppercase", + "data": "QUJDRA==", + "valid": true + }, + { + "description": "Valid - all lowercase", + "data": "cXdlcg==", + "valid": true + }, + { + "description": "Valid - all digits", + "data": "MTIzNDU2Nzg5MA==", + "valid": true + }, + { + "description": "Valid - GIF header", + "data": "R0lGODlhAQABAAAAACw=", + "valid": true + }, + { + "description": "Valid - multiple of 4 chars", + "data": "YWJjZGVmZ2hpamtsbW5vcA==", + "valid": true + }, + { + "description": "Valid - long string", + "data": "VGhpcyBpcyBhIGxvbmcgYmFzZTY0IHVybCBlbmNvZGVkIHN0cmluZyB0aGF0IHNob3VsZCBiZSB2YWxpZA==", + "valid": true + }, + { + "description": "Invalid - one equals padding only", + "data": "YWI==", + "valid": false + }, + { + "description": "Invalid - three equals", + "data": "YQ===", + "valid": false + }, + { + "description": "Invalid - padding in middle", + "data": "YQ==YWI=", + "valid": false + }, + { + "description": "Invalid - padding not at end", + "data": "Y=WI", + "valid": false + }, + { + "description": "Invalid - single character without padding (insufficient data)", + "data": "Y", + "valid": false + }, + { + "description": "Invalid - two characters without required padding", + "data": "YW", + "valid": false + }, + { + "description": "Invalid - three characters without required padding", + "data": "YWJ", + "valid": false + }, + { + "description": "Invalid - contains space", + "data": "YWJj ZA==", + "valid": false + }, + { + "description": "Invalid - contains period", + "data": "YWJj.ZA==", + "valid": false + }, + { + "description": "Invalid - contains comma", + "data": "YWJj,ZA==", + "valid": false + }, + { + "description": "Invalid - contains special char", + "data": "YWJj@ZA==", + "valid": false + }, + { + "description": "Invalid - number type", + "data": 123, + "valid": false + }, + { + "description": "Invalid - boolean type", + "data": true, + "valid": false + }, + { + "description": "Invalid - null type", + "data": null, + "valid": false + }, + { + "description": "Valid - only uppercase letters", + "data": "ABCDEFGH", + "valid": true + }, + { + "description": "Valid - only lowercase letters", + "data": "abcdefgh", + "valid": true + }, + { + "description": "Valid - only digits", + "data": "01234567", + "valid": true + }, + { + "description": "Valid - hyphen at start", + "data": "-ABC", + "valid": true + }, + { + "description": "Valid - underscore at start", + "data": "_ABC", + "valid": true + }, + { + "description": "Valid - hyphen at end", + "data": "ABC-", + "valid": true + }, + { + "description": "Valid - underscore at end", + "data": "ABC_", + "valid": true + }, + { + "description": "Valid - multiple hyphens", + "data": "A-B-C-D-", + "valid": true + }, + { + "description": "Valid - multiple underscores", + "data": "A_B_C_D_", + "valid": true + }, + { + "description": "Valid - hyphen and underscore mixed", + "data": "A-B_C-D_", + "valid": true + }, + { + "description": "Valid - 8 chars no padding", + "data": "ABCDEFGH", + "valid": true + }, + { + "description": "Valid - 12 chars no padding", + "data": "ABCDEFGHIJKL", + "valid": true + }, + { + "description": "Valid - 16 chars no padding", + "data": "ABCDEFGHIJKLMNOP", + "valid": true + }, + { + "description": "Invalid - 5 chars without required padding", + "data": "ABCDE", + "valid": false + }, + { + "description": "Invalid - 6 chars without required padding", + "data": "ABCDEF", + "valid": false + }, + { + "description": "Invalid - 7 chars without required padding", + "data": "ABCDEFG", + "valid": false + }, + { + "description": "Invalid - 10 chars without required padding", + "data": "ABCDEFGHIJ", + "valid": false + }, + { + "description": "Valid - padding with two equals at end of 4-char group", + "data": "AB==", + "valid": true + }, + { + "description": "Valid - padding with one equal at end of 4-char group", + "data": "ABC=", + "valid": true + }, + { + "description": "Valid - 8 chars then padding", + "data": "ABCDEFGH_w==", + "valid": true + }, + { + "description": "Valid - all char types", + "data": "AZ09-_AB", + "valid": true + }, + { + "description": "Valid - repeated patterns", + "data": "AAAABBBBCCCCDDDD", + "valid": true + }, + { + "description": "Valid - zeros encoded", + "data": "AAAA", + "valid": true + }, + { + "description": "Valid - alternating chars", + "data": "AaAaAaAa", + "valid": true + }, + { + "description": "Invalid - padding at beginning", + "data": "==ABCD", + "valid": false + }, + { + "description": "Invalid - padding in first position", + "data": "=ABC", + "valid": false + }, + { + "description": "Invalid - only equals", + "data": "====", + "valid": false + }, + { + "description": "Invalid - single equals", + "data": "=", + "valid": false + }, + { + "description": "Invalid - double equals alone", + "data": "==", + "valid": false + }, + { + "description": "Invalid - four equals", + "data": "ABCD====", + "valid": false + }, + { + "description": "Invalid - padding then more chars", + "data": "AB==CD", + "valid": false + }, + { + "description": "Invalid - padding then padding", + "data": "AB===", + "valid": false + }, + { + "description": "Invalid - mixed padding positions", + "data": "A=B=", + "valid": false + }, + { + "description": "Invalid - three chars with two equals", + "data": "ABC==", + "valid": false + }, + { + "description": "Invalid - two chars with one equal", + "data": "AB=", + "valid": false + }, + { + "description": "Invalid - five chars with padding", + "data": "ABCDE=", + "valid": false + }, + { + "description": "Valid - uppercase G", + "data": "ABCG", + "valid": true + }, + { + "description": "Valid - lowercase g", + "data": "ABCg", + "valid": true + }, + { + "description": "Invalid - contains plus (base64 char, not base64url)", + "data": "ABC+", + "valid": false + }, + { + "description": "Invalid - contains slash (base64 char, not base64url)", + "data": "ABC/", + "valid": false + }, + { + "description": "Invalid - contains (", + "data": "ABC(", + "valid": false + }, + { + "description": "Invalid - contains )", + "data": "ABC)", + "valid": false + }, + { + "description": "Invalid - contains [", + "data": "ABC[", + "valid": false + }, + { + "description": "Invalid - contains ]", + "data": "ABC]", + "valid": false + }, + { + "description": "Invalid - contains {", + "data": "ABC{", + "valid": false + }, + { + "description": "Invalid - contains }", + "data": "ABC}", + "valid": false + }, + { + "description": "Invalid - contains !", + "data": "ABC!", + "valid": false + }, + { + "description": "Invalid - contains ?", + "data": "ABC?", + "valid": false + }, + { + "description": "Invalid - contains *", + "data": "ABC*", + "valid": false + }, + { + "description": "Invalid - contains &", + "data": "ABC&", + "valid": false + }, + { + "description": "Invalid - contains $", + "data": "ABC$", + "valid": false + }, + { + "description": "Invalid - contains %", + "data": "ABC%", + "valid": false + }, + { + "description": "Invalid - contains #", + "data": "ABC#", + "valid": false + }, + { + "description": "Invalid - contains ^", + "data": "ABC^", + "valid": false + }, + { + "description": "Invalid - contains ~", + "data": "ABC~", + "valid": false + }, + { + "description": "Invalid - contains `", + "data": "ABC`", + "valid": false + }, + { + "description": "Invalid - contains |", + "data": "ABC|", + "valid": false + }, + { + "description": "Invalid - contains \\", + "data": "ABC\\", + "valid": false + }, + { + "description": "Invalid - contains ;", + "data": "ABC;", + "valid": false + }, + { + "description": "Invalid - contains :", + "data": "ABC:", + "valid": false + }, + { + "description": "Invalid - contains '", + "data": "ABC'", + "valid": false + }, + { + "description": "Invalid - contains \"", + "data": "ABC\"", + "valid": false + }, + { + "description": "Invalid - contains <", + "data": "ABC<", + "valid": false + }, + { + "description": "Invalid - contains >", + "data": "ABC>", + "valid": false + }, + { + "description": "Invalid - leading tab", + "data": "\tABCD", + "valid": false + }, + { + "description": "Invalid - trailing tab", + "data": "ABCD\t", + "valid": false + }, + { + "description": "Invalid - tab in middle", + "data": "AB\tCD", + "valid": false + }, + { + "description": "Invalid - leading space", + "data": " ABCD", + "valid": false + }, + { + "description": "Invalid - trailing space", + "data": "ABCD ", + "valid": false + }, + { + "description": "Invalid - multiple spaces", + "data": "AB CD", + "valid": false + }, + { + "description": "Invalid - contains newline", + "data": "AB\nCD", + "valid": false + }, + { + "description": "Invalid - contains carriage return", + "data": "AB\rCD", + "valid": false + }, + { + "description": "Invalid - non-ASCII character", + "data": "ABCé", + "valid": false + }, + { + "description": "Invalid - emoji", + "data": "ABC😀", + "valid": false + }, + { + "description": "Valid - very long valid base64url", + "data": "VGhpcyBpcyBhIHZlcnkgbG9uZyBiYXNlNjQgdXJsIGVuY29kZWQgc3RyaW5nIHRoYXQgd2UgYXJlIHVzaW5nIHRvIHRlc3QgdGhlIHZhbGlkYXRpb24gb2YgbG9uZ2VyIGlucHV0cyB0byBtYWtlIHN1cmUgb3VyIHBhdHRlcm4gd29ya3MgY29ycmVjdGx5", + "valid": true + }, + { + "description": "Valid - URL-safe chars only", + "data": "A-Z_09ab", + "valid": true + }, + { + "description": "Invalid - base64 plus in base64url context", + "data": "SGVs+G8h", + "valid": false + }, + { + "description": "Invalid - base64 slash in base64url context", + "data": "SGVs/G8h", + "valid": false + } + ] +}