Merge 3b3eb2f78e7e0f4855ec2334356a20559a3d333f into 4290ea753912378913b1f3f54e0fc5720afeda5d

This commit is contained in:
NOVA 2026-08-10 00:01:11 -07:00 committed by GitHub
commit 4701b2022e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 270 additions and 0 deletions

View File

@ -30,6 +30,8 @@
"From Bech32", "From Bech32",
"To Base62", "To Base62",
"From Base62", "From Base62",
"To Base26",
"From Base26",
"To Base64", "To Base64",
"From Base64", "From Base64",
"Show Base64 offsets", "Show Base64 offsets",

View File

@ -0,0 +1,61 @@
/**
* @author NOVA-Openclaw
* @copyright Crown Copyright 2026
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
/**
* From Base26 operation
*/
class FromBase26 extends Operation {
/**
* FromBase26 constructor
*/
constructor() {
super();
this.name = "From Base26";
this.module = "Default";
this.description = "Base26 is a notation for encoding arbitrary byte data using the uppercase letters A-Z. The input string is interpreted as a radix-26 number using A=0, B=1, ..., Z=25, and converted back to its big-endian byte representation.";
this.infoURL = "https://wikipedia.org/wiki/List_of_numeral_systems";
this.inputType = "string";
this.outputType = "byteArray";
this.args = [];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {byteArray}
*/
run(input, args) {
if (input.length < 1) return [];
const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const re = new RegExp("[^A-Za-z]", "g");
input = input.replace(re, "").toUpperCase();
if (input.length < 1) return [];
let number = 0n;
for (const c of input) {
number = number * 26n + BigInt(ALPHABET.indexOf(c));
}
if (number === 0n) return [0];
const bytes = [];
while (number > 0n) {
bytes.unshift(Number(number & 0xFFn));
number >>= 8n;
}
return bytes;
}
}
export default FromBase26;

View File

@ -0,0 +1,58 @@
/**
* @author NOVA-Openclaw
* @copyright Crown Copyright 2026
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
/**
* To Base26 operation
*/
class ToBase26 extends Operation {
/**
* ToBase26 constructor
*/
constructor() {
super();
this.name = "To Base26";
this.module = "Default";
this.description = "Base26 is a notation for encoding arbitrary byte data using the uppercase letters A-Z. The input bytes are interpreted as a big-endian unsigned integer, which is then represented in radix 26 using A=0, B=1, ..., Z=25.";
this.infoURL = "https://wikipedia.org/wiki/List_of_numeral_systems";
this.inputType = "ArrayBuffer";
this.outputType = "string";
this.args = [];
}
/**
* @param {ArrayBuffer} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
input = new Uint8Array(input);
if (input.length < 1) return "";
const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let number = 0n;
for (const byte of input) {
number = (number << 8n) | BigInt(byte);
}
if (number === 0n) return ALPHABET[0];
let output = "";
while (number > 0n) {
output = ALPHABET[Number(number % 26n)] + output;
number /= 26n;
}
return output;
}
}
export default ToBase26;

View File

@ -0,0 +1,149 @@
/**
* Base26 tests.
*
* @author NOVA-Openclaw
*
* @copyright Crown Copyright 2026
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([
{
name: "To Base26: nothing",
input: "",
expectedOutput: "",
recipeConfig: [
{
op: "To Base26",
args: [],
},
],
},
{
name: "To Base26: EAT -> JYGBS",
input: "EAT",
expectedOutput: "JYGBS",
recipeConfig: [
{
op: "To Base26",
args: [],
},
],
},
{
name: "To Base26: Hello, World!",
input: "Hello, World!",
expectedOutput: "LBVLPVLUNRXHXRHSZIHQLL",
recipeConfig: [
{
op: "To Base26",
args: [],
},
],
},
{
name: "To Base26: UTF-8",
input: "ნუ პანიკას",
expectedOutput: "HLPHPKXWXPTREJHEBQENHKRQAKLFKOWIWEXTDNAOPRQFRQLL",
recipeConfig: [
{
op: "To Base26",
args: [],
},
],
},
{
name: "To Base26: zero byte",
input: "\x00",
expectedOutput: "A",
recipeConfig: [
{
op: "To Base26",
args: [],
},
],
},
{
name: "To Base26: binary",
input: "\x01\x02\x03",
expectedOutput: "DTSL",
recipeConfig: [
{
op: "To Base26",
args: [],
},
],
},
{
name: "From Base26: nothing",
input: "",
expectedOutput: "",
recipeConfig: [
{
op: "From Base26",
args: [],
},
],
},
{
name: "From Base26: JYGBS -> EAT",
input: "JYGBS",
expectedOutput: "EAT",
recipeConfig: [
{
op: "From Base26",
args: [],
},
],
},
{
name: "From Base26: lowercase and ignored characters",
input: "j y-g!b@s",
expectedOutput: "EAT",
recipeConfig: [
{
op: "From Base26",
args: [],
},
],
},
{
name: "From Base26: A -> zero byte",
input: "A",
expectedOutput: "\x00",
recipeConfig: [
{
op: "From Base26",
args: [],
},
],
},
{
name: "From Base26: DTSL -> binary",
input: "DTSL",
expectedOutput: "\x01\x02\x03",
recipeConfig: [
{
op: "From Base26",
args: [],
},
],
},
{
name: "To Base26 round-trip",
input: "The quick brown fox jumps over the lazy dog.",
expectedOutput: "The quick brown fox jumps over the lazy dog.",
recipeConfig: [
{
op: "To Base26",
args: [],
},
{
op: "From Base26",
args: [],
},
],
}
]);