128 lines
2.9 KiB
Go
128 lines
2.9 KiB
Go
package set1
|
|
|
|
const Base64Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
|
const Base64PaddingCharacter = '='
|
|
|
|
func HexDecode(block []byte) (value []byte, success bool) {
|
|
size := len(block)
|
|
|
|
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[block[i]] << 4
|
|
second := hexValues[block[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
|
|
}
|