package main import ( "bufio" "flag" "fmt" "io" "os" "strconv" "strings" "unicode" ) // Function to decode number pairs into characters func decodePair(pair string) rune { alphabet := " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" num, err := strconv.Atoi(pair) if err != nil || num < 0 || num >= len(alphabet) { return rune(-1) // Return -1 if pair is not valid } return rune(alphabet[num]) } // Function to apply the reverse shift and wrap around func applyReverseShift(value, shift int) int { shifted := (value - shift) % 37 if shifted < 0 { shifted += 37 } return shifted } func main() { // Define command-line flags shift := flag.Int("s", 0, "Shift amount for the cipher") flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s [options] <<< \"String\"\n", os.Args[0]) fmt.Fprintf(os.Stderr, " %s [options] < file.txt\n", os.Args[0]) fmt.Fprintf(os.Stderr, " echo \"string\" | %s [options]\n", os.Args[0]) fmt.Fprintf(os.Stderr, "\nDescription:\n") fmt.Fprintf(os.Stderr, " A companion program to numberstation, intended to make easy work of decrypting very basic ciphers for numbers station projects using the logic of nsencode.\n") fmt.Fprintf(os.Stderr, "\nOptions:\n") flag.PrintDefaults() // Print the default flag help information fmt.Fprintf(os.Stderr, "\nExamples:\n") fmt.Fprintf(os.Stderr, " %s -s 2 <<< \"22101 12102 11210 20302 22072 122\"\n", os.Args[0]) fmt.Fprintf(os.Stderr, " %s -s 16 < file.txt\n", os.Args[0]) } flag.Parse() // Check if there is input from stdin info, _ := os.Stdin.Stat() if (info.Mode() & os.ModeCharDevice) != 0 { flag.Usage() os.Exit(1) } // Read all input from stdin reader := bufio.NewReader(os.Stdin) inputBytes, _ := io.ReadAll(reader) input := string(inputBytes) // Remove all spaces and line breaks input = strings.ReplaceAll(input, " ", "") input = strings.ReplaceAll(input, "\n", "") input = strings.TrimSpace(input) var decoded strings.Builder // Decode the input string for i := 0; i < len(input); i += 2 { if i+1 >= len(input) { break // If there's an odd number of characters, break out } pair := input[i : i+2] num, err := strconv.Atoi(pair) if err != nil { continue // Skip invalid pairs } shiftedValue := applyReverseShift(num, *shift) char := decodePair(fmt.Sprintf("%02d", shiftedValue)) if !unicode.IsPrint(char) || char == rune(-1) { continue // Skip invalid characters } decoded.WriteRune(char) } // Output the decoded string fmt.Println(decoded.String()) }