taler-android

Android apps for GNU Taler (wallet, PoS, cashier)
Log | Files | Refs | README | LICENSE

CyptoUtils.kt (2245B)


      1 /*
      2  * This file is part of GNU Taler
      3  * (C) 2022 Taler Systems S.A.
      4  *
      5  * GNU Taler is free software; you can redistribute it and/or modify it under the
      6  * terms of the GNU General Public License as published by the Free Software
      7  * Foundation; either version 3, or (at your option) any later version.
      8  *
      9  * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
     10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11  * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License along with
     14  * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15  */
     16 
     17 package net.taler.common
     18 
     19 import kotlin.math.floor
     20 
     21 object CyptoUtils {
     22     internal fun getValue(c: Char): Int {
     23         val a = when (c) {
     24             'o','O' -> '0'
     25             'i','I','l','L' -> '1'
     26             'u','U' -> 'V'
     27             else -> c
     28         }
     29         if (a in '0'..'9') {
     30             return a - '0'
     31         }
     32         val A = if (a in 'a'..'z') a.uppercaseChar() else a
     33         var dec = 0
     34         if (A in 'A'..'Z') {
     35             if ('I' < A) dec++
     36             if ('L' < A) dec++
     37             if ('O' < A) dec++
     38             if ('U' < A) dec++
     39             return A - 'A' + 10 - dec
     40         }
     41         throw Error("encoding error")
     42     }
     43 
     44     fun decodeCrock(e: String): ByteArray {
     45         val size = e.length
     46         var bitpos = 0
     47         var bitbuf = 0
     48         var readPosition = 0
     49         val outLen = floor((size * 5f) / 8).toInt()
     50         val out = ByteArray(outLen)
     51         var outPos = 0
     52         while (readPosition < size || bitpos > 0) {
     53             if (readPosition < size) {
     54                 val v = getValue(e[readPosition++])
     55                 bitbuf = bitbuf.shl(5).or(v)
     56                 bitpos += 5
     57             }
     58             while (bitpos >= 8) {
     59                 val d = bitbuf.shr(bitpos -8).and(0xff).toByte()
     60                 out[outPos++] = d
     61                 bitpos -= 8
     62             }
     63             if (readPosition == size && bitpos > 0) {
     64                 bitbuf = bitbuf.shl( 8 - bitpos).and(0xff)
     65                 bitpos = if (bitbuf == 0) 0 else 8
     66             }
     67         }
     68         return out
     69     }
     70 
     71 }