package com.chameth.yaotp.util private val alphabet = ('A'..'Z') + ('2'..'7') + '=' fun base32Decode(input: String): ByteArray { val values = padToEights(input).toUpperCase().map(alphabet::indexOf) val bytes = ArrayList() values.chunked(8).forEach { chunk -> // Each chunk of 8 values is mapped on (up to) 5 return bytes: // [A1 A2 A3 A4 A5] [B1 B2 B3 // B4 B5] [C1 C2 C3 C4 C5] [D1 -- only if C is present // D2 D3 D4 D5] [E1 E2 E3 E4 -- only if E is present // E5] [F1 F2 F3 F4 F5] [G1 G2 -- only if F is present // G3 G4 G5] [H1 H2 H3 H4 H5] -- only if H is present if (chunk[0] != 32) bytes.add(((chunk[0] shl 3) or (chunk[1] ushr 2)).toByte()) if (chunk[2] != 32) bytes.add((((chunk[1] and 3) shl 6) or (chunk[2] shl 1) or (chunk[3] ushr 4)).toByte()) if (chunk[4] != 32) bytes.add((((chunk[3] and 15) shl 4) or (chunk[4] ushr 1)).toByte()) if (chunk[5] != 32) bytes.add((((chunk[4] and 1) shl 7) or (chunk[5] shl 2) or (chunk[6] ushr 3)).toByte()) if (chunk[7] != 32) bytes.add((((chunk[6] and 7) shl 5) or chunk[7]).toByte()) } return bytes.toByteArray() } internal fun padToEights(input: String) = input + "=".repeat((8 - input.length % 8) % 8)