// One-Clause BSD License ("1BSD") // // Copyright 2022 Kaz Kylheku // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following condition is // met: // // 1. The source code distribution retains the above copyright notice, // this condition, and the following disclaimer. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. const mora = [ "a", "i", "u", "e", "o", "ya", "yu", "yo", "wa", "ka", "ki", "ku", "ke", "ko", "ga", "gi", "gu", "ge", "go", "sa", "shi", "su", "se", "so", "za", "ji", "zu", "ze", "zo", "ta", "chi", "tsu", "te", "to", "da", "de", "do", "na", "ni", "nu", "ne", "no", "ha", "hi", "fu", "he", "ho", "pa", "pi", "pu", "pe", "po", "ba", "bi", "bu", "be", "bo", "ma", "mi", "mu", "me", "mo", "ra", "ri", "ru", "re", "ro", "kya", "kyu", "kyo", "gya", "gyu", "gyo", "sha", "shu", "sho", "ja", "ju", "jo", "cha", "chu", "cho", "nya", "nyu", "nyo", "hya", "hyu", "hyo", "pya", "pyu", "pyo", "bya", "byu", "byo", "mya", "myu", "myo", "rya", "ryu", "ryo" ]; const digit = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ]; const symbol = [ "!", "#", "@", "$", "%", "^", "&", "*", "?", "/" ]; async function jp_hash_complete(hash) { const view = new DataView(hash); let word = []; let ms = []; for (let i = 0; i < 9; i++) word[i] = view.getUint16(2*i, true); for (i = 0; i < 6; i++) ms[i] = mora[word[i] % mora.length]; const dig = digit[word[6] % digit.length]; const sym = symbol[word[7] % symbol.length]; ms[0] = ms[0][0].toUpperCase() + ms[0].slice(1); switch (word[8] & 7) { case 0: return [ms[0], ms[1], ms[2], sym, ms[3], ms[4], ms[5], dig].join(''); case 1: return [sym, ms[0], ms[1], ms[2], dig, ms[3], ms[4], ms[5]].join(''); case 2: return [ms[0], ms[1], sym, ms[2], ms[3], dig, ms[4], ms[5]].join(''); case 3: return [ms[0], ms[1], dig, ms[2], ms[3], sym, ms[4], ms[5]].join(''); case 4: return [ms[0], ms[1], ms[2], "n", sym, ms[3], ms[4], ms[5], dig].join(''); case 5: return [sym, ms[0], ms[1], ms[2], dig, ms[3], ms[4], ms[5], "n"].join(''); case 6: return [ms[0], ms[1], "n", sym, ms[2], ms[3], dig, ms[4], ms[5]].join(''); case 7: return [ms[0], ms[1], dig, ms[2], ms[3], sym, ms[4], ms[5], "n"].join(''); } } async function jp_hash_start(message) { const encoder = new TextEncoder(); const data = encoder.encode(message); const hash = await crypto.subtle.digest('SHA-256', data); return hash; } async function jphash(message, cont) { jp_hash_start(message).then(jp_hash_complete).then(cont); } async function jp_hash_edit(elem) { if (elem.nodeType == 1 && (elem.nodeName == "INPUT" || elem.nodeName == "TEXTAREA")) { jphash(elem.value, (jph) => { elem.value = jph; }); } }