| 1 | // Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved. |
| 2 | // Use of this source code is governed by an MIT license |
| 3 | // that can be found in the LICENSE file. |
| 4 | // Based off: https://github.com/golang/go/blob/master/src/encoding/base64/base64.go |
| 5 | // Last commit: https://github.com/golang/go/commit/9a93baf4d7d13d7d5c67388c93960d78abc8e11e |
| 6 | module base64 |
| 7 | |
| 8 | const index = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 9 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, 56, 57, |
| 10 | 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, |
| 11 | 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, |
| 12 | 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51]! |
| 13 | const ending_table = [0, 2, 1]! |
| 14 | const enc_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' |
| 15 | |
| 16 | // url_decode returns a decoded URL `string` version of |
| 17 | // the a base64 url encoded `string` passed in `data`. |
| 18 | pub fn url_decode(data string) []u8 { |
| 19 | mut result := data.replace_each(['-', '+', '_', '/']) |
| 20 | match result.len % 4 { |
| 21 | // Pad with trailing '='s |
| 22 | 2 { result += '==' } // 2 pad chars |
| 23 | 3 { result += '=' } // 1 pad char |
| 24 | else {} // no padding |
| 25 | } |
| 26 | |
| 27 | return decode(result) |
| 28 | } |
| 29 | |
| 30 | // url_decode_str is the string variant of url_decode |
| 31 | pub fn url_decode_str(data string) string { |
| 32 | mut result := data.replace_each(['-', '+', '_', '/']) |
| 33 | match result.len % 4 { |
| 34 | // Pad with trailing '='s |
| 35 | 2 { result += '==' } // 2 pad chars |
| 36 | 3 { result += '=' } // 1 pad char |
| 37 | else {} // no padding |
| 38 | } |
| 39 | |
| 40 | return decode_str(result) |
| 41 | } |
| 42 | |
| 43 | // url_encode returns a base64 URL encoded `string` version |
| 44 | // of the value passed in `data`. |
| 45 | pub fn url_encode(data []u8) string { |
| 46 | return encode(data).replace_each(['+', '-', '/', '_', '=', '']) |
| 47 | } |
| 48 | |
| 49 | // url_encode_str is the string variant of url_encode |
| 50 | pub fn url_encode_str(data string) string { |
| 51 | return encode_str(data).replace_each(['+', '-', '/', '_', '=', '']) |
| 52 | } |
| 53 | |
| 54 | // assemble64 assembles 8 base64 digits into 6 bytes. |
| 55 | // Each digit comes from the decode map. |
| 56 | // Please note: Invalid base64 digits are not expected and not handled. |
| 57 | fn assemble64(n1 u8, n2 u8, n3 u8, n4 u8, n5 u8, n6 u8, n7 u8, n8 u8) u64 { |
| 58 | return u64(n1) << 58 | u64(n2) << 52 | u64(n3) << 46 | u64(n4) << 40 | u64(n5) << 34 | u64(n6) << 28 | u64(n7) << 22 | u64(n8) << 16 |
| 59 | } |
| 60 | |
| 61 | // assemble32 assembles 4 base64 digits into 3 bytes. |
| 62 | // Each digit comes from the decode map. |
| 63 | // Please note: Invalid base64 digits are not expected and not handled. |
| 64 | fn assemble32(n1 u8, n2 u8, n3 u8, n4 u8) u32 { |
| 65 | return u32(n1) << 26 | u32(n2) << 20 | u32(n3) << 14 | u32(n4) << 8 |
| 66 | } |
| 67 | |