Added grouping functionality

master
Aaron Johnon 1 year ago
parent 9c161acc1b
commit 2686154c6f

@ -11,12 +11,21 @@ import (
) )
func main() { func main() {
// Define the shift, hex, and space flags // Define the shift, hex, space, and grouping flags
shift := flag.Int("s", 0, "Shift value for alphabet positions (can be negative)") shift := flag.Int("s", 0, "Shift value for alphabet positions (can be negative)")
useHex := flag.Bool("x", false, "Encode numbers in hexadecimal") useHex := flag.Bool("x", false, "Encode numbers in hexadecimal")
encodeSpaces := flag.Bool("S", false, "Encode spaces as '00'") encodeSpaces := flag.Bool("S", false, "Encode spaces as '00'")
groupSize := flag.Int("g", 2, "Group size for output digits (minimum value of 2, default 2)")
flag.Parse() flag.Parse()
// Check for invalid group size
if *groupSize == 1 {
fmt.Fprintln(os.Stderr, "Error: Minimum group size is 2. Exiting.")
os.Exit(1)
} else if *groupSize <= 0 {
*groupSize = 2
}
// Check if input is being piped or passed as an argument // Check if input is being piped or passed as an argument
stat, _ := os.Stdin.Stat() stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) != 0 { if (stat.Mode() & os.ModeCharDevice) != 0 {
@ -42,7 +51,7 @@ func main() {
if unicode.IsLetter(char) { if unicode.IsLetter(char) {
// If there was a number being processed, add it to the result first // If there was a number being processed, add it to the result first
if currentNumber != "" { if currentNumber != "" {
appendNumber(&result, currentNumber, *useHex) appendNumber(&result, currentNumber, *useHex, *groupSize)
currentNumber = "" currentNumber = ""
} }
// Get the position of the character in the alphabet (A = 1, B = 2, ..., Z = 26) // Get the position of the character in the alphabet (A = 1, B = 2, ..., Z = 26)
@ -62,14 +71,14 @@ func main() {
} else if char == ' ' && *encodeSpaces { } else if char == ' ' && *encodeSpaces {
// Encode space as '00' if the -S flag is set // Encode space as '00' if the -S flag is set
if currentNumber != "" { if currentNumber != "" {
appendNumber(&result, currentNumber, *useHex) appendNumber(&result, currentNumber, *useHex, *groupSize)
currentNumber = "" currentNumber = ""
} }
result = append(result, "00") result = append(result, "00")
} else { } else {
// If there was a number being processed and now a non-digit/non-letter appears, append it // If there was a number being processed and now a non-digit/non-letter appears, append it
if currentNumber != "" { if currentNumber != "" {
appendNumber(&result, currentNumber, *useHex) appendNumber(&result, currentNumber, *useHex, *groupSize)
currentNumber = "" currentNumber = ""
} }
} }
@ -77,22 +86,95 @@ func main() {
// If there's any remaining number at the end of the input, append it // If there's any remaining number at the end of the input, append it
if currentNumber != "" { if currentNumber != "" {
appendNumber(&result, currentNumber, *useHex) appendNumber(&result, currentNumber, *useHex, *groupSize)
} }
// Join the result slice into a space-separated string and print it // Format output with proper grouping
fmt.Println(strings.Join(result, " ")) finalOutput := groupOutput(result, *groupSize)
fmt.Println(finalOutput)
} }
// appendNumber appends a formatted number to the result slice // appendNumber appends a formatted number to the result slice
func appendNumber(result *[]string, number string, useHex bool) { func appendNumber(result *[]string, number string, useHex bool, groupSize int) {
if useHex { var formatted string
num, err := strconv.Atoi(number) num, err := strconv.Atoi(number)
if err == nil { if err != nil {
*result = append(*result, fmt.Sprintf("0x%X", num)) return
}
// Set maximum values based on group size and mode
var maxValue int
if groupSize == 2 || groupSize == 4 {
if useHex {
maxValue = 255 // 0xFF
} else {
maxValue = 99 // 0d99
} }
} else { } else {
*result = append(*result, "0d"+number) maxDigits := groupSize - 2 // for "0x" or "0d" prefix
maxValue = intMaxValue(useHex, maxDigits)
} }
if num > maxValue {
fmt.Fprintf(os.Stderr, "Warning: Number %d is too large for group size %d. Using maximum value %d.\n", num, groupSize, maxValue)
num = maxValue
}
if useHex {
formatted = fmt.Sprintf("0x%X", num)
} else {
formatted = fmt.Sprintf("0d%d", num)
}
*result = append(*result, formatted)
}
// intMaxValue calculates the maximum value that fits within the specified group size
func intMaxValue(useHex bool, maxDigits int) int {
if useHex {
return (1 << uint(maxDigits*4)) - 1 // Maximum hexadecimal value fitting in maxDigits
}
return intPow(10, maxDigits) - 1 // Maximum decimal value fitting in maxDigits
}
// intPow calculates integer power
func intPow(base, exp int) int {
result := 1
for exp > 0 {
result *= base
exp--
}
return result
}
// groupOutput groups the output into specified sizes, ensuring numbers are separate
func groupOutput(result []string, groupSize int) string {
var output []string
var currentGroup string
for _, item := range result {
if strings.HasPrefix(item, "0x") || strings.HasPrefix(item, "0d") {
// If the current group is not empty, add it to the output
if currentGroup != "" {
output = append(output, currentGroup)
currentGroup = ""
}
// Numbers are placed in their own group
output = append(output, item)
} else {
currentGroup += item
if len(currentGroup) >= groupSize {
output = append(output, currentGroup[:groupSize])
currentGroup = currentGroup[groupSize:]
}
}
}
// Append any remaining characters in the current group
if currentGroup != "" {
output = append(output, currentGroup)
}
return strings.Join(output, " ")
} }

Loading…
Cancel
Save