Base64Encode encodes the received input bytes slice into a base64 string. The implementation follows the RFC4648 standard, which is documented at https://datatracker.ietf.org/doc/html/rfc4648#section-4
(input []byte)
| 19 | // The implementation follows the RFC4648 standard, which is documented |
| 20 | // at https://datatracker.ietf.org/doc/html/rfc4648#section-4 |
| 21 | func Base64Encode(input []byte) string { |
| 22 | var sb strings.Builder |
| 23 | // If not 24 bits (3 bytes) multiple, pad with 0 value bytes, and with "=" for the output |
| 24 | var padding string |
| 25 | for i := len(input) % 3; i > 0 && i < 3; i++ { |
| 26 | var zeroByte byte |
| 27 | input = append(input, zeroByte) |
| 28 | padding += "=" |
| 29 | } |
| 30 | |
| 31 | // encode 24 bits per 24 bits (3 bytes per 3 bytes) |
| 32 | for i := 0; i < len(input); i += 3 { |
| 33 | // select 3 8-bit input groups, and re-arrange them into 4 6-bit groups |
| 34 | // the literal 0x3F corresponds to the byte "0011 1111" |
| 35 | // the operation "byte & 0x3F" masks the two left-most bits |
| 36 | group := [4]byte{ |
| 37 | input[i] >> 2, |
| 38 | (input[i]<<4)&0x3F + input[i+1]>>4, |
| 39 | (input[i+1]<<2)&0x3F + input[i+2]>>6, |
| 40 | input[i+2] & 0x3F, |
| 41 | } |
| 42 | |
| 43 | // translate each group into a char using the static map |
| 44 | for _, b := range group { |
| 45 | sb.WriteString(string(Alphabet[int(b)])) |
| 46 | } |
| 47 | } |
| 48 | encoded := sb.String() |
| 49 | |
| 50 | // Apply the output padding |
| 51 | encoded = encoded[:len(encoded)-len(padding)] + padding[:] |
| 52 | |
| 53 | return encoded |
| 54 | } |
| 55 | |
| 56 | // Base64Decode decodes the received input base64 string into a byte slice. |
| 57 | // The implementation follows the RFC4648 standard, which is documented |