Skip to content

feat(groq): A whimsical Go CLI that converts any text into an 8×8 ASCII QR‑like code using SHA‑256 hashing.#4253

Open
polsala wants to merge 1 commit intomainfrom
ai/groq-20260418-1313
Open

feat(groq): A whimsical Go CLI that converts any text into an 8×8 ASCII QR‑like code using SHA‑256 hashing.#4253
polsala wants to merge 1 commit intomainfrom
ai/groq-20260418-1313

Conversation

@polsala
Copy link
Copy Markdown
Owner

@polsala polsala commented Apr 18, 2026

Implementation Summary

  • Utility: nightly-qr-crypt
  • Provider: groq
  • Location: go-utils/nightly-nightly-qr-crypt
  • Files Created: 3
  • Description: A whimsical Go CLI that converts any text into an 8×8 ASCII QR‑like code using SHA‑256 hashing.

Rationale

  • Automated proposal from the Groq generator delivering a fresh community utility.
  • This utility was generated using the groq AI provider.

Why safe to merge

  • Utility is isolated to go-utils/nightly-nightly-qr-crypt.
  • README + tests ship together (see folder contents).
  • No secrets or credentials touched.
  • All changes are additive and self-contained.

Test Plan

  • Follow the instructions in the generated README at go-utils/nightly-nightly-qr-crypt/README.md
  • Run tests located in go-utils/nightly-nightly-qr-crypt/tests/

Links

  • Generated docs and examples committed alongside this change.

Mock Justification

  • Not applicable; generator did not introduce new mocks.

@polsala
Copy link
Copy Markdown
Owner Author

polsala commented Apr 18, 2026

🤖 Review by GROQ Agent

✅ What's solid

  • Self‑contained implementation – The CLI lives entirely in src/main.go and has no external dependencies beyond the Go standard library.
  • Deterministic output – By hashing the input with SHA‑256 and using the first 64 bits, the same string always yields the same 8×8 pattern, which the README highlights.
  • Clear user feedback – When no argument is supplied the program prints a concise usage line and exits with a non‑zero status, matching typical CLI conventions.
  • Readable code – Variable names (hash, grid, input) are expressive, and the bit‑extraction loop is straightforward to follow.

🧪 Tests

  • Coverage is minimal – Only a single happy‑path test (TestGenerateQR) is present. Consider adding:

    • A test for an empty string (should still produce a valid 8×8 grid).
    • A test that supplies multiple CLI arguments and verifies they are concatenated (or that the program rejects them, depending on intended behavior).
    • Property‑based test confirming that the output length is always 8*8 + 7 characters (64 cells plus 7 newline separators).
  • Potential fragility of the expected pattern – The expected string is hard‑coded. If the bit‑ordering logic changes (e.g., switching to LSB‑first), the test will break. To make the test more resilient, you could generate the expected pattern programmatically from the known hash:

    func expectedPatternFromHash(hash [32]byte) string {
        var b strings.Builder
        for i := 0; i < 8; i++ {
            for bit := 7; bit >= 0; bit-- {
                if (hash[i]>>bit)&1 == 1 {
                    b.WriteByte('#')
                } else {
                    b.WriteByte(' ')
                }
            }
            if i < 7 {
                b.WriteByte('\n')
            }
        }
        return b.String()
    }
    
    func TestGenerateQR_Deterministic(t *testing.T) {
        input := "test"
        h := sha256.Sum256([]byte(input))
        want := expectedPatternFromHash(h)
        if got := generateQR(input); got != want {
            t.Fatalf("mismatch")
        }
    }
  • Use of t.Fatalf vs t.Errorf – Since the mismatch is a single assertion, t.Fatalf is fine, but if you later add multiple sub‑checks, switching to t.Errorf with t.FailNow() after all checks can give richer failure output.

🔒 Security

  • No external secrets – The utility does not read environment variables, files, or network resources, so the surface for credential leakage is nil.

  • Input handling – The program directly forwards the first CLI argument to the hash function. This is safe because SHA‑256 treats the input as opaque bytes. However, consider sanitising or quoting when the tool is used in shells that perform expansion (e.g., spaces, wildcards). Documenting that the argument should be quoted is helpful.

  • Potential DoS via huge inputs – While Go’s []byte conversion can handle large strings, an attacker could pass a multi‑gigabyte argument causing high memory usage. Adding a reasonable size guard (e.g., reject inputs > 1 MiB) would make the CLI more robust:

    const maxInputSize = 1 << 20 // 1 MiB
    if len(input) > maxInputSize {
        fmt.Fprintln(os.Stderr, "error: input too large (max 1 MiB)")
        os.Exit(2)
    }

🧩 Docs / Developer Experience

  • README completeness – The README covers installation, usage, and an example output. A few enhancements:

    • Add a “Building” section that explicitly mentions go mod tidy if the utility lives in its own module.
    • Clarify that all arguments after the program name are treated as a single string, or state that only the first argument is used (current behavior).
    • Provide a quick sanity check command, e.g., go run src/main.go "test" | wc -c to verify the output size.
  • Help output – The usage line prints Usage: qrcrypt <text> but does not include the actual binary name. Using os.Args[0] yields a more accurate message:

    fmt.Printf("Usage: %s <text>\n", filepath.Base(os.Args[0]))
  • License notice – The MIT license is mentioned, but adding a LICENSE file at the repository root (if not already present) ensures compliance with tooling that scans for license files.

🧱 Mocks / Fakes

  • Not applicable – The utility does not depend on external services or interfaces, so no mocks are required.
  • Future extensibility – If you later decide to abstract the hashing algorithm (e.g., to allow SHA‑1 or a custom hash), defining a Hasher interface would enable unit‑testing with deterministic fake hashers.

Overall impression: The CLI is a tidy, well‑documented addition that fulfills its whimsical purpose. Strengthening the test suite, tightening input size handling, and polishing the usage message will make the utility more robust and developer‑friendly without altering its core charm.

@polsala
Copy link
Copy Markdown
Owner Author

polsala commented Apr 18, 2026

🤖 Review by GEMINI Agent

✅ What's solid

  • Self-contained and minimal dependencies – The utility is entirely self-contained within src/main.go and relies only on the Go standard library, making it easy to understand and deploy.
  • Deterministic output – The use of SHA-256 hashing ensures that the same input always produces the identical 8x8 ASCII pattern, as clearly highlighted in the README.md.
  • Clear usage instructions – The CLI provides a helpful usage message when invoked without arguments, guiding the user on how to provide input.
  • Comprehensive README.md – The documentation clearly explains the utility's purpose, provides usage examples for both go run and go build, and includes an illustrative output example.

🧪 Tests

  • Expand test coverage for generateQR: The existing TestGenerateQR provides a solid baseline for a single input. Consider adding more test cases to cover a wider range of inputs for the generateQR function, such as:
    • An empty string ("").
    • A very long string to ensure consistent behavior.
    • Strings containing various Unicode characters or special symbols.
  • Consider main function testing: While testing os.Exit directly can be challenging, explore options to verify the main function's behavior, particularly its argument parsing and output for missing arguments. This might involve temporarily redirecting os.Stdout and os.Stderr in a test helper.

🔒 Security

  • Input length considerations: The utility directly processes os.Args[1] without explicit length validation. While Go's string handling is robust, for extremely large inputs, consider adding a maximum input length check to prevent potential (though unlikely for this utility) resource exhaustion or to provide more graceful error handling for excessively long strings.
    const MaxInputLength = 1024 // Example limit
    if len(input) > MaxInputLength {
        fmt.Fprintf(os.Stderr, "Error: Input exceeds maximum allowed length of %d characters.\n", MaxInputLength)
        os.Exit(1)
    }

🧩 Docs/DX

  • Path consistency: The utility's directory path go-utils/nightly-nightly-qr-crypt contains a repetitive "nightly". Ensure consistency with the intended name nightly-qr-crypt used in the README.md and PR title.
  • Clarify "QR-like" nature: While the README.md describes the tool as "whimsical" and producing "QR-like" patterns, explicitly stating that the output is not a standard QR code and cannot be scanned by QR readers would help manage user expectations.
  • Standard help flag: For improved CLI user experience, consider implementing a standard help flag (e.g., -h or --help) that displays the usage message, rather than only showing it when arguments are entirely missing.
    func main() {
        if len(os.Args) < 2 || os.Args[1] == "-h" || os.Args[1] == "--help" {
            fmt.Println("Usage: qrcrypt <text>")
            os.Exit(1)
        }
        // ... rest of the main function
    }

🧱 Mocks/Fakes

  • No mocks required: The current design of nightly-qr-crypt is a self-contained utility with no external dependencies or complex state that would necessitate the use of mocks or fakes for testing. This simplicity is a positive aspect of the implementation.

@polsala
Copy link
Copy Markdown
Owner Author

polsala commented Apr 19, 2026

🤖 Review by OPENROUTER Agent

✅ What's solid

  • Self-contained implementation – The entire utility resides in src/main.go, relying solely on the Go standard library. This makes the tool portable and easy to audit.
  • Deterministic behavior – Using SHA-256 ensures consistent outputs for identical inputs, which is well-documented and tested.
  • Clear entry point and error handling – The CLI provides a helpful usage message when invoked incorrectly (len(os.Args) < 2).

🧪 Tests

  • ✅ Basic functionality covered via one test case in tests/main_test.go.
  • 🔧 Actionable Feedback: Consider adding more test cases to cover edge scenarios such as:
    • Empty string input
    • Unicode characters
    • Very long strings
    • Special symbols

Example enhancement:

func TestGenerateQREdgeCases(t *testing.T) {
    cases := []struct {
        input    string
        expected string
    }{
        {"", "<expected-empty-output>"},
        {"🚀", "<expected-hash-for-rocket>"},
    }

    for _, c := range cases {
        got := generateQR(c.input)
        if got != c.expected {
            t.Errorf("generateQR(%q) = %q; want %q", c.input, got, c.expected)
        }
    }
}

🔒 Security

  • ✅ No sensitive data or credentials involved.
  • ⚠️ Note: While not critical for a demo/utility tool, using only the first 64 bits of a hash may reduce entropy compared to full QR codes. For production-grade applications, consider expanding the grid size or incorporating additional obfuscation layers.

🧩 Docs/DX

  • ✅ Clear and concise README with example usage and output.
  • 🔧 Actionable Feedback:
    • Add installation instructions for users unfamiliar with Go workflows.
    • Clarify that the output isn't a true QR code but a visual cryptographic token.
    • Suggest possible extensions like saving output to file or integrating into scripts.

Enhanced snippet suggestion for README:

## Installation

Ensure [Go](https://golang.org/dl/) is installed:

```bash
go install github.com/apocalypsai/go-utils/nightly-nightly-qr-crypt@latest

Then run directly:

nightly-nightly-qr-crypt "your message"

🧱 Mocks/Fakes  
* Not applicable — no external dependencies or network calls requiring mocking were introduced. Future enhancements involving APIs should include mock-based testing strategies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant