diff --git a/conversion/hexadecimaltobinary.go b/conversion/hexadecimaltobinary.go new file mode 100644 index 000000000..2eecb0d71 --- /dev/null +++ b/conversion/hexadecimaltobinary.go @@ -0,0 +1,48 @@ +/* +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" + "strconv" + "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 + decimal, err := strconv.ParseInt(hex, 16, 64) + if err != nil { + return "", errors.New("failed to parse hexadecimal string " + hex + ": " + err.Error()) + } + + // Convert the integer to a binary string + binary := strconv.FormatInt(decimal, 2) + return binary, nil +} diff --git a/conversion/hexadecimaltobinary_test.go b/conversion/hexadecimaltobinary_test.go new file mode 100644 index 000000000..c2dee9712 --- /dev/null +++ b/conversion/hexadecimaltobinary_test.go @@ -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") + } +} diff --git a/conversion/hexadecimaltodecimal.go b/conversion/hexadecimaltodecimal.go new file mode 100644 index 000000000..ece3389f9 --- /dev/null +++ b/conversion/hexadecimaltodecimal.go @@ -0,0 +1,49 @@ +/* +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" + "strconv" + "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") + } + + // Convert the hexadecimal string to a decimal integer + decimalValue, err := strconv.ParseInt(hexStr, 16, 64) + if err != nil { + return 0, fmt.Errorf("invalid hexadecimal string: %v", err) + } + + return decimalValue, nil +} diff --git a/conversion/hexadecimaltodecimal_test.go b/conversion/hexadecimaltodecimal_test.go new file mode 100644 index 000000000..4f399fe46 --- /dev/null +++ b/conversion/hexadecimaltodecimal_test.go @@ -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") + } +}