Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions conversion/hexadecimaltobinary.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
Author: mapcrafter2048
GitHub: https://github.com/mapcrafter2048
*/

// This algorithm will convert any Hexadecimal number(0-9, A-F, a-f) to Binary number(0 or 1).
// https://en.wikipedia.org/wiki/Hexadecimal
// https://en.wikipedia.org/wiki/Binary_number
// Function receives a Hexadecimal Number as string and returns the Binary number as string.
// Supported Hexadecimal number range is 0 to 7FFFFFFFFFFFFFFF.

package conversion

import (
"errors"
"regexp"
"strings"
)

var isValidHex = regexp.MustCompile("^[0-9A-Fa-f]+$").MatchString

// hexToBinary() function that will take Hexadecimal number as string,
// and return its Binary equivalent as a string.
func hexToBinary(hex string) (string, error) {
// Trim any leading or trailing whitespace
hex = strings.TrimSpace(hex)

// Check if the hexadecimal string is empty
if hex == "" {
return "", errors.New("input string is empty")
}

// Check if the hexadecimal string is valid
if !isValidHex(hex) {
return "", errors.New("invalid hexadecimal string: " + hex)
}

// Parse the hexadecimal string to an integer
var decimal int64
for i := 0; i < len(hex); i++ {
char := hex[i]
var value int64
if char >= '0' && char <= '9' {
value = int64(char - '0')
} else if char >= 'A' && char <= 'F' {
value = int64(char - 'A' + 10)
} else if char >= 'a' && char <= 'f' {
value = int64(char - 'a' + 10)
} else {
return "", errors.New("invalid character in hexadecimal string: " + string(char))
}
decimal = decimal*16 + value
}

// Convert the integer to a binary string without using predefined functions
var binaryBuilder strings.Builder
if decimal == 0 {
binaryBuilder.WriteString("0")
} else {
for decimal > 0 {
bit := decimal % 2
if bit == 0 {
binaryBuilder.WriteString("0")
} else {
binaryBuilder.WriteString("1")
}
decimal = decimal / 2
}
}

// Reverse the binary string since the bits are added in reverse order
binaryRunes := []rune(binaryBuilder.String())
for i, j := 0, len(binaryRunes)-1; i < j; i, j = i+1, j-1 {
binaryRunes[i], binaryRunes[j] = binaryRunes[j], binaryRunes[i]
}

return string(binaryRunes), nil
}
46 changes: 46 additions & 0 deletions conversion/hexadecimaltobinary_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package conversion

import (
"testing"
)

func TestHexToBinary(t *testing.T) {
tests := []struct {
hex string
want string
wantErr bool
}{
{"", "", true},
{"G123", "", true},
{"12XZ", "", true},
{"1", "1", false},
{"A", "1010", false},
{"10", "10000", false},
{"1A", "11010", false},
{"aB", "10101011", false},
{"0Ff", "11111111", false},
{" 1A ", "11010", false},
{"0001A", "11010", false},
{"7FFFFFFFFFFFFFFF", "111111111111111111111111111111111111111111111111111111111111111", false},
}

for _, tt := range tests {
t.Run(tt.hex, func(t *testing.T) {
got, err := hexToBinary(tt.hex)
if (err != nil) != tt.wantErr {
t.Errorf("hexToBinary(%q) error = %v, wantErr %v", tt.hex, err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("hexToBinary(%q) = %v, want %v", tt.hex, got, tt.want)
}
})
}
}

func BenchmarkHexToBinary(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_, _ = hexToBinary("7FFFFFFFFFFFFFFF")
}
}
57 changes: 57 additions & 0 deletions conversion/hexadecimaltodecimal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Author: mapcrafter2048
GitHub: https://github.com/mapcrafter2048
*/

// This algorithm will convert any Hexadecimal number(0-9, A-F, a-f) to Decimal number(0-9).
// https://en.wikipedia.org/wiki/Hexadecimal
// https://en.wikipedia.org/wiki/Decimal
// Function receives a Hexadecimal Number as string and returns the Decimal number as integer.
// Supported Hexadecimal number range is 0 to 7FFFFFFFFFFFFFFF.

package conversion

import (
"fmt"
"regexp"
"strings"
)

var isValidHexadecimal = regexp.MustCompile("^[0-9A-Fa-f]+$").MatchString

// hexToDecimal converts a hexadecimal string to a decimal integer.
func hexToDecimal(hexStr string) (int64, error) {

hexStr = strings.TrimSpace(hexStr)

if len(hexStr) == 0 {
return 0, fmt.Errorf("input string is empty")
}

// Check if the string has a valid hexadecimal prefix
if len(hexStr) > 2 && (hexStr[:2] == "0x" || hexStr[:2] == "0X") {
hexStr = hexStr[2:]
}

// Validate the hexadecimal string
if !isValidHexadecimal(hexStr) {
return 0, fmt.Errorf("invalid hexadecimal string")
}

var decimalValue int64
for _, char := range hexStr {
var digit int64
if char >= '0' && char <= '9' {
digit = int64(char - '0')
} else if char >= 'A' && char <= 'F' {
digit = int64(char - 'A' + 10)
} else if char >= 'a' && char <= 'f' {
digit = int64(char - 'a' + 10)
} else {
return 0, fmt.Errorf("invalid character in hexadecimal string: %c", char)
}
decimalValue = decimalValue*16 + digit
}

return decimalValue, nil
}
52 changes: 52 additions & 0 deletions conversion/hexadecimaltodecimal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package conversion

import (
"testing"
)

func TestHexToDecimal(t *testing.T) {
tests := []struct {
hex string
want int64
wantErr bool
}{
{"", 0, true},
{"G123", 0, true},
{"123Z", 0, true},
{"1", 1, false},
{"A", 10, false},
{"10", 16, false},
{"1A", 26, false},
{"aB", 171, false},
{"0Ff", 255, false},
{" 1A ", 26, false},
{"0x1A", 26, false},
{"0X1A", 26, false},
{"1A", 26, false},
{"7FFFFFFFFFFFFFFF", 9223372036854775807, false},
{"0001A", 26, false},
{"0000007F", 127, false},
{"0", 0, false},
{"0x0", 0, false},
}

for _, tt := range tests {
t.Run(tt.hex, func(t *testing.T) {
got, err := hexToDecimal(tt.hex)
if (err != nil) != tt.wantErr {
t.Errorf("hexToDecimal(%q) error = %v, wantErr %v", tt.hex, err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("hexToDecimal(%q) = %v, want %v", tt.hex, got, tt.want)
}
})
}
}

func BenchmarkHexToDecimal(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_, _ = hexToDecimal("7FFFFFFFFFFFFFFF")
}
}
Loading