aboutsummaryrefslogtreecommitdiffstats
path: root/firefox/jp-hash.js
blob: 1072b4b591a0d06d074d880bcd94d1e477c2c204 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// One-Clause BSD License ("1BSD")
//
// Copyright 2022  Kaz Kylheku <kaz@kylheku.com>
//
// 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; });
  }
}