viroman

Base64 utf8 decoder without external dependencies

1 post in this topic

#1 ·  Posted (edited)

Hello,

just looked around and googled for a proper way to decode base64 utf8 encoded strings and did not find good examples. So created own.

Additionally includes base64 utf8 encoder.

Possibly some one finds it useful.

Used https://www.base64encode.org/ to encode base64-utf8

Global $b64 = StringSplit("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", "", 2);

Func _getBase64Num($a)
    $a = Asc($a)
    If $a > 47 And $a < 58 Then
        Return $a + 4;
    ElseIf $a > 64 And $a < 91 Then
        Return $a - 65;
    ElseIf $a > 96 And $a < 123 Then
        Return $a - 71;
    ElseIf $a = 43 Then
        Return 62
    ElseIf $a = 47 Then
        Return 63
    Else
        Return 64
    EndIf
EndFunc

Func _base64dec_arr($r)
      While StringCompare(StringLeft($r, 1), " ", 1) = 0
          $r = StringMid($r, 2)
      WEnd
      Local $a, $d, $t, $c, $n, $o, $h, $i, $b = 0, $f = 0;
      If(StringLen($r) < 1) Then Return $r;
      Local $rlen = StringLen($r)
      Local $g = [1]
      Redim $g[Ceiling($rlen * 0.75)]
      $r = StringSplit($r, "", 2);
      While $b < $rlen
        $c = _getBase64Num($r[$b])
        $b = $b + 1;
        $n = _getBase64Num($r[$b])
        $b = $b + 1;
        $o = _getBase64Num($r[$b])
        $b = $b + 1;
        $h = _getBase64Num($r[$b])
        $b = $b + 1;
        $i = BitOR(BitShift($c, -18), BitShift($n, -12), BitShift($o, -6), $h)
        $a = BitAND(BitShift($i, 16), 255)
        $d = BitAND(BitShift($i, 8), 255)
        $t = BitAND(255, $i)
        If $o = 64 Then
          $g[$f] = $a
          $f = $f + 1;
        ElseIf $h = 64 Then
          $g[$f] = $a
          $f = $f + 1;
          $g[$f] = $d
          $f = $f + 1;
        Else
          $g[$f] = $a
          $f = $f + 1;
          $g[$f] = $d
          $f = $f + 1;
          $g[$f] = $t
          $f = $f + 1;
        EndIf
      WEnd
      If UBound($g) <> $f Then
        Redim $g[$f]
      EndIf
      Return $g; returns array
EndFunc;

Func _utf8_decode($str_data) ;expects array
        Local $tmp_arr = "", $i = 0, $c1, $c2, $c3, $strlen = UBound($str_data);

        While $i < $strlen
            $c1 = $str_data[$i];
            If $c1 < 128 Then
                $tmp_arr = $tmp_arr & ChrW($c1);
                $i = $i + 1;
            ElseIf $c1 > 191 And $c1 < 224 Then
                $c2 = $str_data[$i + 1];
                $tmp_arr = $tmp_arr & ChrW(BitOR(BitShift(BitAND($c1, 31), -6), BitAND($c2, 63)));
                $i = $i + 2;
            Else
                $c2 = $str_data[$i + 1];
                $c3 = $str_data[$i + 2];
                $tmp_arr = $tmp_arr & ChrW(BitOR(BitShift(BitAND($c1, 15), -12), BitShift(BitAND($c2, 63), -6), BitAND($c3, 63)));
                $i = $i + 3;
            EndIf
        WEnd
        Return $tmp_arr;
EndFunc;

Func _base64_utf8_dec($a)
    Return _utf8_decode(_base64dec_arr($a))
EndFunc

Func _utf8_base64_enc($a)
    Return _base64_enc(_utf8_encode($a))
EndFunc

Func _utf8_encode($stringOr)
        Local $utftext = "", $start = 0, $end = 0, $n = 0, $c1, $enc;
        Local $string = StringSplit($stringOr, "", 2);
        Local $stringl = UBound($string)
        While $n < $stringl
          $c1 = AscW($string[$n])
          If $c1 > 127 Then
            If $c1 < 2048 Then
              $enc = ChrW(BitOR(BitShift($c1, 6), 192)) & ChrW(BitOR(BitAND($c1, 63), 128))
            Else
              $enc = ChrW(BitOR(BitShift($c1, 12), 224)) & ChrW(BitOR(BitAND(BitShift($c1, 6), 63), 128)) & ChrW(BitOR(BitAND($c1, 63), 128))
            EndIf
            If $end > $start Then
              $utftext = $utftext & StringMid($stringOr, $start + 1, $end - $start)
            EndIf
            $utftext = $utftext & $enc;
            $n = $n + 1;
            $start = $n;
          Else
            $n = $n + 1;
          EndIf
          $end = $n;
        WEnd

        If $end > $start Then
           $utftext = $utftext & StringMid($stringOr, $start + 1, $stringl - $start)
        EndIf
        Return $utftext;
EndFunc;

Func _base64_enc($rOr)
        Local $e, $t, $h, $o, $d = 0, $b = "";
        Local $r = StringSplit($rOr, "", 2);
        Local $rL = UBound($r)

        While $d < $rL
          $e = AscW($r[$d])
          $d = $d + 1;
          If $d < $rL Then
            $t = AscW($r[$d])
          Else
            $t = 0;
          EndIf
          $d = $d + 1;
          If $d < $rL Then
            $h = AscW($r[$d])
          Else
            $h = 0;
          EndIf
          $d = $d + 1;

          $o = BitOR(BitShift($e, -16), BitShift($t, -8), $h)
          $b = $b & $b64[BitAND(BitShift($o, 18), 63)] & $b64[BitAND(BitShift($o, 12), 63)] & $b64[BitAND(BitShift($o, 6), 63)] & $b64[BitAND(63, $o)]
        WEnd
        $rL = Mod($rL, 3);
        If $rL = 1 Then
          $b = StringLeft($b, StringLen($b) - 2) & "==";
        ElseIf $rL = 2 Then
          $b = StringLeft($b, StringLen($b) - 1) & "=";
        EndIf
        Return $b
EndFunc;

MsgBox(0, _utf8_base64_enc("your string"), _base64_utf8_dec("eW91ciBzdHJpbmc="));

 

 

base64_dec_enc_utf8.au3

Edited by viroman

Share this post


Link to post
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now