Note: This was deprecated, please use this instead: https://luatnd.github.io/caesar-password/
The simple encrypt by combining simple encoding + password method:
-
phrase was split into words by space seperator:
"hello world this is an example"
=>['hello', 'world', 'this', 'is', 'an', 'example']
-
words will be encoded by a customized caesar cypher encoding:
supported_chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
password = "your free password"
-
encode by base64:
'.....'
-
finish => Save this info into your cloud file for safety.
Security: Caesar can be bruteforce, but with your strong password, it's hard to be brute force
// TODO: Make a public website to host this
(function main() {
plain_text = "this is your mnemonic word phrases"
password = 'TestMyP@ss_complex'
const encoded_text = encode_all(plain_text, password)
const decoded_text = decode_all(encoded_text, password)
console.log('plain_text, decoded_text, encoded_text: ', "\n", plain_text, "\n", decoded_text, "\n", encoded_text)
console.assert(plain_text === decoded_text, {plain_text, decoded_text, encoded_text})
console.log("This is your encoded phrases, please save it to your cloud file, should not share it for everyone else: ", encoded_text)
console.log("Must not and never share this password for anyone, you're the only one who know this: ", password)
console.log("If you need the plain mnemonic phrase to import it to another wallet, use this function to show your mnemonic: decode_all(your_encoded_phrases, your_password)")
})()
(function test() {
test_special_chars = '_+--=~!@#$%^&* ()__â ơ ê ỉ ắ á';
plain_text = "Hello world w3 @re the best of gen Y abcdefghijklmnopqrstuvwxyz1234567890"
plain_text += test_special_chars;
password = 'TestMyP@ss_complex'
const encoded_text = encode_all(plain_text, password)
const decoded_text = decode_all(encoded_text, password)
console.log('plain_text, decoded_text, encoded_text: ', "\n", plain_text, "\n", decoded_text, "\n", encoded_text)
console.assert(plain_text === decoded_text, {plain_text, decoded_text, encoded_text})
})()
function encode_all(all_word_string, password) {
plains = all_word_string.split(' ')
encodes = []
plains.forEach(plain => {
let encoded, decoded;
// Encode latin word only
if (isLatinOnly(plain)) {
encoded = pass_encode(plain, password);
decoded = pass_decode(encoded, password);
} else {
encoded = plain
decoded = plain
}
encodes.push(encoded)
const fn = plain === decoded ? console.info : console.error;
fn(`"${plain}", "${encoded}", "${decoded}"`)
})
return encodes.join(' ')
}
function decode_all(all_decoded_string, password) {
decoded_words = all_decoded_string.split(' ')
plains = []
decoded_words.forEach(encoded => {
let plain;
if (isLatinOnly(encoded)) {
plain = pass_decode(encoded, password);
}
else {
plain = encoded
}
plains.push(plain)
console.log(`"${encoded}", "${plain}"`)
})
return plains.join(' ')
}
// only supported_chars was encoded
function pass_encode(plain_text, password) {
return base64_encode(caesar_cypher_with_password(plain_text, password))
}
function pass_decode(encoded_text, password) {
return caesar_cypher_with_password(base64_decode(encoded_text), password, true)
}
function caesar_cypher_with_password(plain_text, password, decoding = false) {
const supported_chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
const supported_chars_indexes = toReverseDict(supported_chars);
/**
* encode/decode a single char
* shift can be negative
*/
function caesar_cypher(char, shift) {
const prev_idx = supported_chars_indexes[char]
const new_idx = (prev_idx + shift + supported_chars.length) % supported_chars.length;
return supported_chars[new_idx];
}
function makeShiftValues(password) {
const shifts = [];
for(let i = 0, c = password.length; i < c; i++) {
const charCode = supported_chars_indexes[password[i]];
const shift = (charCode ?? 0) % supported_chars.length;
shifts.push(shift);
}
return shifts;
}
// console.log('makeShiftValues', makeShiftValues(supported_chars + est_special_chars))
/*
* encode plain text with multiple shift values
* In case of single shift: shifts = [shift_value]
*/
function caesar_cypher_with_shifts(plain_text, shifts) {
let encoded = '';
if (!shifts.length) shifts.push(0); // no password mean not shifting
for(let i = 0, c = plain_text.length; i < c; i++) {
const char = plain_text[i];
if (char in supported_chars_indexes) {
const shift = shifts[i % shifts.length]
encoded += caesar_cypher(char, shift)
} else {
// console.log('skip')
encoded += char;
}
}
return encoded;
}
let shifts = makeShiftValues(password);
// shift of decoding is reversed compared to encoding
if (decoding) {
shifts = shifts.map(i => -i);
}
return caesar_cypher_with_shifts(plain_text, shifts)
}
function toReverseDict(arr) {
const dict = {}
for(let i = 0, c = arr.length; i < c; i++) dict[arr[i]] = i;
return dict;
}
function base64_encode(plain) {
return btoa(plain)
}
function base64_decode(encoded) {
return atob(encoded)
}
function isLatinOnly(s) {
for(let i = 0, c = s.length; i < c; i++) {
if (s.charCodeAt(i) > 255) return false;
}
return true;
}
Why using this: