Category: Uncategorized

  • I Built HashForge: A Privacy-First Hash Generator That Shows All Algorithms at Once

    I’ve been hashing things for years — verifying file downloads, generating checksums for deployments, creating HMAC signatures for APIs. And every single time, I end up bouncing between three or four browser tabs because no hash tool does everything I need in one place.

    So I built HashForge.

    The Problem with Existing Hash Tools

    Here’s what frustrated me about the current landscape. Most online hash generators force you to pick one algorithm at a time. Need MD5 and SHA-256 for the same input? That’s two separate page loads. Browserling’s tools, for example, have a different page for every algorithm — MD5 on one URL, SHA-256 on another, SHA-512 on yet another. You’re constantly copying, pasting, and navigating.

    Then there’s the privacy problem. Some hash generators process your input on their servers. For a tool that developers use with sensitive data — API keys, passwords, config files — that’s a non-starter. Your input should never leave your machine.

    And finally, most tools feel like they were built in 2010 and never updated. No dark mode, no mobile responsiveness, no keyboard shortcuts. They work, but they feel dated.

    What Makes HashForge Different

    All algorithms at once. Type or paste text, and you instantly see MD5, SHA-1, SHA-256, SHA-384, and SHA-512 hashes side by side. No page switching, no dropdown menus. Every algorithm, every time, updated in real-time as you type.

    Four modes in one tool. HashForge isn’t just a text hasher. It has four distinct modes:

    • Text mode: Real-time hashing as you type. Supports hex, Base64, and uppercase hex output.
    • File mode: Drag-and-drop any file — PDFs, ISOs, executables, anything. The file never leaves your browser. There’s a progress indicator for large files and it handles multi-gigabyte files using the Web Crypto API’s native streaming.
    • HMAC mode: Enter a secret key and message to generate HMAC signatures for SHA-1, SHA-256, SHA-384, and SHA-512. Essential for API development and webhook verification.
    • Verify mode: Paste two hashes and instantly compare them. Uses constant-time comparison to prevent timing attacks — the same approach used in production authentication systems.

    100% browser-side processing. Nothing — not a single byte — leaves your browser. HashForge uses the Web Crypto API for SHA algorithms and a pure JavaScript implementation for MD5 (since the Web Crypto API doesn’t support MD5). There’s no server, no analytics endpoint collecting your inputs, no “we process your data according to our privacy policy” fine print. Your data stays on your device, period.

    Technical Deep Dive

    HashForge is a single HTML file — 31KB total with all CSS and JavaScript inline. Zero external dependencies. No frameworks, no build tools, no CDN requests. This means:

    • First paint under 100ms on any modern browser
    • Works offline after the first visit (it’s a PWA with a service worker)
    • No supply chain risk — there’s literally nothing to compromise

    The MD5 Challenge

    The Web Crypto API supports SHA-1, SHA-256, SHA-384, and SHA-512 natively, but not MD5. Since MD5 is still widely used for file verification (despite being cryptographically broken), I implemented it in pure JavaScript. The implementation handles the full MD5 specification — message padding, word array conversion, and all four rounds of the compression function.

    Is MD5 secure? No. Should you use it for passwords? Absolutely not. But for verifying that a file downloaded correctly? It’s fine, and millions of software projects still publish MD5 checksums alongside SHA-256 ones.

    Constant-Time Comparison

    The hash verification mode uses constant-time comparison. In a naive string comparison, the function returns as soon as it finds a mismatched character — which means comparing “abc” against “axc” is faster than comparing “abc” against “abd”. An attacker could theoretically use this timing difference to guess a hash one character at a time.

    HashForge’s comparison XORs every byte of both hashes and accumulates the result, then checks if the total is zero. The operation takes the same amount of time regardless of where (or whether) the hashes differ. This is the same pattern used in OpenSSL’s CRYPTO_memcmp and Node.js’s crypto.timingSafeEqual.

    PWA and Offline Support

    HashForge registers a service worker that caches the page on first visit. After that, it works completely offline — no internet required. The service worker uses a network-first strategy: it tries to fetch the latest version, falls back to cache if you’re offline. This means you always get updates when connected, but never lose functionality when you’re not.

    Accessibility

    Every interactive element has proper ARIA attributes. The tab navigation follows the WAI-ARIA Tabs Pattern — arrow keys move between tabs, Home/End jump to first/last. There’s a skip-to-content link for screen reader users. All buttons have visible focus states. Keyboard shortcuts (Ctrl+1 through Ctrl+4) switch between modes.

    Real-World Use Cases

    1. Verifying software downloads. You download an ISO and the website provides a SHA-256 checksum. Drop the file into HashForge’s File mode, copy the SHA-256 output, paste it into Verify mode alongside the published checksum. Instant verification.

    2. API webhook signature verification. Stripe, GitHub, and Slack all use HMAC-SHA256 to sign webhooks. When debugging webhook handlers, you can use HashForge’s HMAC mode to manually compute the expected signature and compare it against what you’re receiving. No need to write a throwaway script.

    3. Generating content hashes for ETags. Building a static site? Hash your content to generate ETags for HTTP caching. Paste the content into Text mode, grab the SHA-256, and you have a cache key.

    4. Comparing database migration checksums. After running a migration, hash the schema dump and compare it across environments. HashForge’s Verify mode makes this a two-paste operation.

    5. Quick password hash lookups. Not for security — but when you’re debugging and need to quickly check if two plaintext values produce the same hash (checking for normalization issues, encoding problems, etc.).

    What I Didn’t Build

    I deliberately left out some features that other tools include:

    • No bcrypt/scrypt/argon2. These are password hashing algorithms, not general-purpose hash functions. They’re intentionally slow and have different APIs. Mixing them in would confuse the purpose of the tool.
    • No server-side processing. Some tools offer an “API” where you POST data and get hashes back. Why? The browser can do this natively.
    • No accounts or saved history. Hash a thing, get the result, move on. If you need to save it, copy it. Simple tools should be simple.

    Try It

    HashForge is free, open-source, and runs entirely in your browser. Try it at hashforge.orthogonal.info.

    If you find it useful, buy me a coffee — it helps me keep building privacy-first tools.

    For developers: the source is on GitHub. It’s a single HTML file, so feel free to fork it, self-host it, or tear it apart to see how it works.

    Looking for more browser-based dev tools? Check out QuickShrink (image compression), PixelStrip (EXIF removal), and TypeFast (text snippets). All free, all private, all single-file.

    Looking for a great mechanical keyboard to speed up your development workflow? I’ve been using one for years and the tactile feedback genuinely helps with coding sessions. The Keychron K2 is my daily driver — compact 75% layout, hot-swappable switches, and excellent build quality. Also worth considering: a solid USB-C hub makes the multi-monitor developer setup much cleaner.

  • I Built JSON Forge: A Privacy-First JSON Formatter That Runs Entirely in Your Browser

    Every developer works with JSON. APIs return it, configs use it, databases store it. And every developer has, at some point, pasted a giant blob of minified JSON into an online formatter and thought: “Wait, did I just send my API keys to some random server?”

    That’s why I built JSON Forge — a JSON formatter, validator, and explorer that processes everything in your browser. Zero data leaves your machine. No accounts, no cookies, no tracking pixels. Just you and your JSON.

    The Problem with Existing JSON Formatters

    I analyzed the top three JSON formatting tools on the web before building mine. Here’s what I found:

    • jsonformatter.org — Cluttered with ads, sluggish on large files, and the UI feels like it hasn’t been updated since 2015. Keyboard shortcuts? Forget about it.
    • jsonformatter.curiousconcept.com — Cleaner interface, but it sends your data to their server for processing. For formatting JSON. On a server. In 2026.
    • jsoneditoronline.org — Feature-rich but overwhelming. It wants you to create an account for basic features. The tree view is nice but the learning curve is steep.

    None of them hit the sweet spot: powerful enough for daily use, simple enough that you don’t need a tutorial, and private enough that you’d paste your production database config into it without hesitation.

    What JSON Forge Does Differently

    JSON Forge is a single HTML file. No npm, no build step, no framework, no dependencies. You can literally download it, disconnect from the internet, and it works perfectly. Here’s what makes it special:

    1. True Privacy by Architecture

    This isn’t a marketing claim — it’s a technical guarantee. JSON Forge has zero network requests for data processing. The JavaScript JSON.parse() and JSON.stringify() run in your browser’s V8/SpiderMonkey/JavaScriptCore engine. Your data never touches a wire.

    As a Progressive Web App (PWA), you can install it and use it completely offline. The service worker caches all assets on first load.

    2. Keyboard-Driven Workflow

    I designed JSON Forge for developers who live in their keyboard. Here are the shortcuts:

    • Ctrl+Enter — Format/Beautify
    • Ctrl+Shift+M — Minify
    • Ctrl+Shift+C — Copy output to clipboard
    • Ctrl+F — Search within JSON
    • Ctrl+Shift+S — Sort keys alphabetically
    • Tab — Insert 2 spaces (proper indentation in the editor)
    • Escape — Close search/modals

    No mouse required. Paste your JSON, hit Ctrl+Enter, then Ctrl+Shift+C. Done in under a second.

    3. Dual View: Code + Tree

    Toggle between syntax-highlighted code view and an interactive tree view. The tree view is collapsible, and clicking any node reveals its JSONPath in the breadcrumb bar at the bottom. Click the path to copy it — incredibly useful when you need to reference a deeply nested field in code.

    Large nested objects (depth > 2 with more than 5 children) automatically collapse to keep the tree manageable. You can expand them with a single click.

    4. Smart Auto-Fix

    Hit the 🔧 Fix button and JSON Forge attempts to repair common mistakes:

    • Trailing commas{"a": 1,}{"a": 1}
    • Single quotes{\'name\': \'test\'}{"name": "test"}
    • Unquoted keys{name: "test"}{"name": "test"}

    These are the three most common copy-paste errors when moving JSON between JavaScript code and actual JSON. The fix is applied before parsing, so it handles the cases where JSON.parse() would normally throw.

    How It Works Under the Hood

    The entire app is a single HTML file (~38KB). Here’s the technical architecture:

    Syntax Highlighting

    I use regex-based highlighting on the already-formatted JSON string. Each line is processed to identify:

    • Keys (purple) — strings followed by a colon
    • String values (green) — quoted strings not followed by a colon
    • Numbers (orange) — numeric literals including scientific notation
    • Booleans (red) — true/false
    • Null (gray) — the null keyword

    For files larger than 500KB, I skip highlighting entirely and use textContent instead of innerHTML. This prevents the browser from choking on massive DOM trees. At 500KB, you’re looking at roughly 10,000+ lines — syntax highlighting becomes more of a liability than a feature.

    Tree View Rendering

    The tree is built recursively with document.createElement calls. Each node tracks its own collapsed state via closure variables — no external state management needed. The toggle event listeners use stopPropagation() to prevent click events from bubbling up and triggering parent node selections.

    I added an auto-collapse heuristic: nodes at depth > 2 with more than 5 children start collapsed. This keeps the initial tree render fast and prevents the user from being overwhelmed by deeply nested API responses.

    PWA / Service Worker

    The service worker uses a cache-first strategy with network fallback. On install, it pre-caches the HTML, manifest, and itself. On subsequent requests, it serves from cache first and updates in the background. This means the app loads instantly even on slow connections — and works completely offline after the first visit.

    // Cache-first with network fallback
    self.addEventListener('fetch', e => {
      e.respondWith(
        caches.match(e.request).then(r =>
          r || fetch(e.request).then(resp => {
            const clone = resp.clone();
            caches.open(CACHE).then(c => c.put(e.request, clone));
            return resp;
          })
        )
      );
    });

    Resizable Panels

    The input/output panels are resizable via a draggable divider. On desktop, it’s a vertical split with horizontal dragging. On mobile (≤768px viewport), the layout switches to a vertical stack with a horizontal divider. The resize logic clamps the split between 20% and 80% to prevent either panel from becoming unusable.

    Performance Characteristics

    I tested JSON Forge with various file sizes:

    • 1KB — Parses in <1ms, renders instantly
    • 100KB — Parses in ~5ms, highlighting in ~20ms
    • 1MB — Parses in ~30ms, highlighting in ~200ms
    • 10MB — Parses in ~300ms, falls back to plain text (no highlighting)
    • 50MB — The maximum file size for drag-and-drop, parses in ~2s

    The 500KB threshold for disabling syntax highlighting was chosen empirically. Below that, the DOM manipulation for highlighting adds negligible time. Above it, we’re creating tens of thousands of <span> elements, which causes visible jank on mid-range devices.

    Design Decisions

    No dependencies. Not even for the UI. The CSS is custom-written using CSS custom properties for theming. Dark mode uses prefers-color-scheme: dark with a media query that swaps all color variables. Total CSS is ~200 lines.

    Single file. Everything — HTML, CSS, and JavaScript — lives in one file. This isn’t laziness; it’s intentional. A single file is trivially deployable, cacheable, and inspectable. You can curl it, save it, and you have the entire app.

    Debounced validation. The input textarea has a 300ms debounced validator that shows a green ✓ or red ✗ badge in the output header. This gives you instant feedback on whether your JSON is valid without the overhead of continuous parsing.

    Drag and drop. Developers often have .json files on their desktop. Drop them directly onto the input area. The FileReader API reads the file as text, and auto-formatting kicks in.

    Try It

    JSON Forge is live at jsonforge.orthogonal.info. It’s also available as a PWA — hit the install button in your browser’s address bar to add it to your desktop or home screen.

    The source code is on GitHub. It’s part of our App Factory — a collection of privacy-first web tools that includes QuickShrink (image compression), PixelStrip (metadata removal), and TypeFast (typing trainer).

    If JSON Forge saves you time, consider buying me a coffee ☕ — it keeps the lights on and the tools free.

    What’s Next

    I’m considering a few enhancements for future versions:

    • JSON Schema validation — Paste a schema alongside your JSON and get inline validation errors
    • Diff mode — Compare two JSON objects side-by-side with highlighted differences
    • JMESPath / JSONPath querying — Filter and extract data from large JSON structures
    • JSON-to-TypeScript/Python/Go type generation — Auto-generate type definitions from your JSON data

    These would all remain 100% client-side. Privacy isn’t a feature — it’s the foundation.

    Happy formatting. 🔧