package set1 const Base64Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" const Base64PaddingCharacter = "=" func HexDecode(hex string) (value []byte, success bool) { size := len(hex) var hexValues = map[byte]byte{ '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14, 'f': 15, } if size%2 != 0 { return []byte{}, false } buffer := make([]byte, 0, size/2) for i := 0; i < size; i += 2 { first := hexValues[hex[i]] << 4 second := hexValues[hex[i+1]] buffer = append(buffer, first^second) } return buffer, true } // NOTE: Unused func Base64Encode(value string) (base64 string) { originalBytes := []byte(value) size := len(originalBytes) buffer := make([]byte, 0, size+size/3) for i := 0; i < size; i += 3 { // TODO: Handle end case to add padding originals := originalBytes[i : i+3] first := originals[0] >> 2 second := (0b00110000 & (originals[0] << 4)) ^ (originals[1] >> 4) third := (0b00111100 & (originals[1] << 2)) ^ (originals[2] >> 6) fourth := 0b00111111 & originals[2] buffer = append(buffer, Base64Alphabet[first], Base64Alphabet[second], Base64Alphabet[third], Base64Alphabet[fourth]) } return string(buffer) } func HexToBase64(hexValue string) (base64 string, success bool) { hexSize := len(hexValue) var hexValues = map[byte]byte{ '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14, 'f': 15, } if hexSize%2 != 0 { return "", false } plainBuffer := make([]byte, 0, hexSize/2) for i := 0; i < hexSize; i += 2 { first := hexValues[hexValue[i]] << 4 second := hexValues[hexValue[i+1]] plainBuffer = append(plainBuffer, first^second) } plainSize := len(plainBuffer) base64Buffer := make([]byte, 0, plainSize+plainSize/3) for i := 0; i < plainSize; i += 3 { // TODO: Handle end case to add padding originals := plainBuffer[i : i+3] // Base64 splits up 3 bytes into 4 by first taking all 24 bits of the original 3 bytes and splitting them evenly across 4 6-bit words // Example: byte A: 0bAAAAAAAA, byte B: 0bBBBBBBBB, byte C: 0bCCCCCCCC // Base64 Result: 0b00AAAAAA, 0b00AABBBB, 0b00BBCCCC, 0b00CCCCCC // This expands the size of the original data by ~33% // If the byte size of the original data is not divisible by 3, the missing bytes are padded out to 0s and the padding character = is used to the end of the base64 string first := originals[0] >> 2 second := (0b00110000 & (originals[0] << 4)) ^ (originals[1] >> 4) third := (0b00111100 & (originals[1] << 2)) ^ (originals[2] >> 6) fourth := 0b00111111 & originals[2] base64Buffer = append(base64Buffer, Base64Alphabet[first], Base64Alphabet[second], Base64Alphabet[third], Base64Alphabet[fourth]) } return string(base64Buffer), true }