add untested faert implementation
This commit is contained in:
@@ -0,0 +1,398 @@
|
||||
/**
|
||||
* FÆRT: Fast Æternity Recovery Text
|
||||
*
|
||||
* Reference: https://gitlab.com/zxq9/passgas/-/blob/83607fedb08be5dfd03210e331f9c76125bb3467/fullofbeans
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
export {
|
||||
encode,
|
||||
decode,
|
||||
byte_of_word,
|
||||
check_word,
|
||||
check_byte,
|
||||
words
|
||||
}
|
||||
|
||||
import * as safe from './safe.js';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Encode a bytestring into FÆRT
|
||||
*/
|
||||
function
|
||||
encode
|
||||
(bytes : Uint8Array)
|
||||
: string
|
||||
{
|
||||
// initial accumulator
|
||||
let words_acc : Array<string> = [];
|
||||
|
||||
// go along each byte and look up the word
|
||||
// add it to the accumulator
|
||||
for (let this_byte of bytes) {
|
||||
let this_word = words[this_byte];
|
||||
words_acc.push(this_word);
|
||||
}
|
||||
|
||||
// prepend check word to phrase
|
||||
// yes craig it would be faster to do the check byte inline
|
||||
// the usage case here is 64 byte strings
|
||||
// double pass is not a big deal
|
||||
return check_word(bytes) + ' ' + words_acc.join(' ');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Decode a FAERT string into bytes
|
||||
*/
|
||||
function
|
||||
decode
|
||||
(faert : string)
|
||||
: safe.Safe<Uint8Array, string>
|
||||
{
|
||||
let all_words : Array<string> = faert.split(' ');
|
||||
let input_check_word : string = all_words[0];
|
||||
let input_words : Array<string> = all_words.slice(1)
|
||||
|
||||
// accumulator
|
||||
let computed_bytes : Array<number> = [];
|
||||
|
||||
// loop over words and figure out accumulator
|
||||
for (let this_input_word of input_words) {
|
||||
let maybe_this_byte : safe.Safe<number, string> = byte_of_word(this_input_word);
|
||||
// if the word is an allowable word, add it to the accumulator
|
||||
if (maybe_this_byte.ok) {
|
||||
let this_byte : number = maybe_this_byte.result;
|
||||
computed_bytes.push(this_byte);
|
||||
}
|
||||
// error case, propagate the error up the call chain
|
||||
else {
|
||||
return maybe_this_byte;
|
||||
}
|
||||
}
|
||||
|
||||
// at this point, we can assume we correctly decoded all words
|
||||
// compute the check byte
|
||||
let computed_check_word : string = check_word(computed_bytes);
|
||||
|
||||
// check if it is correct
|
||||
// if so, return the computed bytes
|
||||
if (computed_check_word === input_check_word) {
|
||||
return safe.ok(new Uint8Array(computed_bytes));
|
||||
}
|
||||
// otherwise, return an error
|
||||
else {
|
||||
return safe.error('checksum failure! computed check word: ' + computed_check_word + '; input check word: ' + input_check_word);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* given a word, find its index
|
||||
*/
|
||||
function
|
||||
byte_of_word
|
||||
(word: string)
|
||||
: safe.Safe<number, string>
|
||||
{
|
||||
for (let i=0; i<=255, i++) {
|
||||
if (word == words[i])
|
||||
return safe.ok(i);
|
||||
}
|
||||
return safe.error('invalid word: ' + word);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* compute the check word of an array
|
||||
*/
|
||||
function
|
||||
check_word
|
||||
(bytes: Uint8Array)
|
||||
: string
|
||||
{
|
||||
return words[check_byte(bytes)];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* given an array, compute the xor of all the bytes in the array
|
||||
*/
|
||||
function
|
||||
check_byte
|
||||
(bytes: Uint8Array)
|
||||
: number
|
||||
{
|
||||
let check_byte = 0;
|
||||
for (let this_byte of bytes) {
|
||||
check_byte ^= this_byte;
|
||||
}
|
||||
return check_byte;
|
||||
}
|
||||
|
||||
|
||||
|
||||
words = [
|
||||
"able",
|
||||
"abuse",
|
||||
"acquire",
|
||||
"adjust",
|
||||
"agent",
|
||||
"air",
|
||||
"alert",
|
||||
"alpha",
|
||||
"anger",
|
||||
"answer",
|
||||
"any",
|
||||
"argue",
|
||||
"around",
|
||||
"assume",
|
||||
"asthma",
|
||||
"aunt",
|
||||
"awkward",
|
||||
"balcony",
|
||||
"barrel",
|
||||
"because",
|
||||
"behave",
|
||||
"bicycle",
|
||||
"bike",
|
||||
"blind",
|
||||
"blouse",
|
||||
"bonus",
|
||||
"bottom",
|
||||
"breeze",
|
||||
"brother",
|
||||
"bubble",
|
||||
"burger",
|
||||
"butter",
|
||||
"can",
|
||||
"cannon",
|
||||
"cargo",
|
||||
"catalog",
|
||||
"caught",
|
||||
"century",
|
||||
"chaos",
|
||||
"chicken",
|
||||
"churn",
|
||||
"cinnamon",
|
||||
"clever",
|
||||
"clock",
|
||||
"clown",
|
||||
"collect",
|
||||
"conduct",
|
||||
"convince",
|
||||
"correct",
|
||||
"cradle",
|
||||
"crane",
|
||||
"crime",
|
||||
"cross",
|
||||
"crystal",
|
||||
"curve",
|
||||
"daughter",
|
||||
"debris",
|
||||
"decrease",
|
||||
"deny",
|
||||
"deputy",
|
||||
"despair",
|
||||
"diesel",
|
||||
"dinner",
|
||||
"distance",
|
||||
"document",
|
||||
"donate",
|
||||
"drama",
|
||||
"drink",
|
||||
"dutch",
|
||||
"earth",
|
||||
"educate",
|
||||
"elbow",
|
||||
"employ",
|
||||
"endless",
|
||||
"enlist",
|
||||
"enter",
|
||||
"equal",
|
||||
"eternal",
|
||||
"example",
|
||||
"exhibit",
|
||||
"exotic",
|
||||
"faculty",
|
||||
"famous",
|
||||
"fault",
|
||||
"feature",
|
||||
"fiber",
|
||||
"filter",
|
||||
"firm",
|
||||
"flame",
|
||||
"flush",
|
||||
"follow",
|
||||
"forward",
|
||||
"frame",
|
||||
"fringe",
|
||||
"future",
|
||||
"game",
|
||||
"gate",
|
||||
"gift",
|
||||
"glare",
|
||||
"glow",
|
||||
"goat",
|
||||
"grab",
|
||||
"grief",
|
||||
"guilt",
|
||||
"hand",
|
||||
"hawk",
|
||||
"health",
|
||||
"hen",
|
||||
"hire",
|
||||
"honey",
|
||||
"hover",
|
||||
"hurry",
|
||||
"hybrid",
|
||||
"impose",
|
||||
"inch",
|
||||
"inherit",
|
||||
"injury",
|
||||
"install",
|
||||
"iron",
|
||||
"jazz",
|
||||
"joke",
|
||||
"just",
|
||||
"kit",
|
||||
"kitchen",
|
||||
"language",
|
||||
"laundry",
|
||||
"leader",
|
||||
"lend",
|
||||
"leopard",
|
||||
"license",
|
||||
"live",
|
||||
"lobster",
|
||||
"lounge",
|
||||
"magnet",
|
||||
"mail",
|
||||
"mansion",
|
||||
"mass",
|
||||
"math",
|
||||
"media",
|
||||
"message",
|
||||
"metal",
|
||||
"misery",
|
||||
"mix",
|
||||
"more",
|
||||
"mountain",
|
||||
"museum",
|
||||
"mutual",
|
||||
"narrow",
|
||||
"nerve",
|
||||
"next",
|
||||
"note",
|
||||
"obey",
|
||||
"obtain",
|
||||
"offer",
|
||||
"once",
|
||||
"orange",
|
||||
"ostrich",
|
||||
"over",
|
||||
"owner",
|
||||
"palace",
|
||||
"patch",
|
||||
"pave",
|
||||
"pen",
|
||||
"phrase",
|
||||
"piece",
|
||||
"pizza",
|
||||
"plunge",
|
||||
"polar",
|
||||
"pool",
|
||||
"power",
|
||||
"pretty",
|
||||
"private",
|
||||
"protect",
|
||||
"pulp",
|
||||
"purity",
|
||||
"quit",
|
||||
"quote",
|
||||
"raise",
|
||||
"razor",
|
||||
"recall",
|
||||
"region",
|
||||
"relief",
|
||||
"rent",
|
||||
"rescue",
|
||||
"review",
|
||||
"ride",
|
||||
"risk",
|
||||
"roof",
|
||||
"rough",
|
||||
"saddle",
|
||||
"salmon",
|
||||
"sand",
|
||||
"scene",
|
||||
"scrub",
|
||||
"season",
|
||||
"seek",
|
||||
"series",
|
||||
"shed",
|
||||
"shoe",
|
||||
"sick",
|
||||
"silent",
|
||||
"situate",
|
||||
"skill",
|
||||
"slide",
|
||||
"slush",
|
||||
"snack",
|
||||
"solar",
|
||||
"soul",
|
||||
"special",
|
||||
"sphere",
|
||||
"spot",
|
||||
"spy",
|
||||
"stairs",
|
||||
"stereo",
|
||||
"strategy",
|
||||
"stuff",
|
||||
"success",
|
||||
"sunny",
|
||||
"surge",
|
||||
"swear",
|
||||
"symptom",
|
||||
"tail",
|
||||
"ten",
|
||||
"tent",
|
||||
"theme",
|
||||
"thumb",
|
||||
"tiny",
|
||||
"toe",
|
||||
"tooth",
|
||||
"topic",
|
||||
"trade",
|
||||
"trash",
|
||||
"trophy",
|
||||
"truly",
|
||||
"tumble",
|
||||
"typical",
|
||||
"uncle",
|
||||
"unfair",
|
||||
"until",
|
||||
"upper",
|
||||
"useless",
|
||||
"van",
|
||||
"venue",
|
||||
"video",
|
||||
"visa",
|
||||
"vocal",
|
||||
"walk",
|
||||
"waste",
|
||||
"wedding",
|
||||
"weekend",
|
||||
"wide",
|
||||
"winner",
|
||||
"wise",
|
||||
"wood",
|
||||
"wrist",
|
||||
"zero"
|
||||
]
|
||||
Reference in New Issue
Block a user