summaryrefslogtreecommitdiff
path: root/packages/taler-util/src/rfc3548.ts
blob: 2dd18cdfccd7a5f7db20925ea179bbe86210d4f6 (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
/*
 This file is part of GNU Taler
 (C) 2024 Taler Systems SA

 GNU Taler is free software; you can redistribute it and/or modify it under the
 terms of the GNU General Public License as published by the Free Software
 Foundation; either version 3, or (at your option) any later version.

 GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

 You should have received a copy of the GNU General Public License along with
 GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */

import { getRandomBytes } from "./taler-crypto.js";

const encTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";

/**
 * base32 RFC 3548
 */
export function encodeRfc3548Base32(data: ArrayBuffer) {
  const dataBytes = new Uint8Array(data);
  let sb = "";
  const size = data.byteLength;
  let bitBuf = 0;
  let numBits = 0;
  let pos = 0;
  while (pos < size || numBits > 0) {
    if (pos < size && numBits < 5) {
      const d = dataBytes[pos++];
      bitBuf = (bitBuf << 8) | d;
      numBits += 8;
    }
    if (numBits < 5) {
      // zero-padding
      bitBuf = bitBuf << (5 - numBits);
      numBits = 5;
    }
    const v = (bitBuf >>> (numBits - 5)) & 31;
    sb += encTable[v];
    numBits -= 5;
  }
  return sb;
}

export function isRfc3548Base32Charset(s: string): boolean {
  for (let idx = 0; idx < s.length; idx++) {
    const c = s.charAt(idx);
    if (encTable.indexOf(c) === -1) return false;
  }
  return true;
}

export function randomRfc3548Base32Key(): string {
  const buf = getRandomBytes(20);
  return encodeRfc3548Base32(buf);
}