<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: pulkitgovrani</title>
    <description>The latest articles on DEV Community by pulkitgovrani (@pulkitgovrani).</description>
    <link>https://dev.to/pulkitgovrani</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F405919%2F8cab8c52-f8c7-4f58-bbe8-46cc0851e135.png</url>
      <title>DEV Community: pulkitgovrani</title>
      <link>https://dev.to/pulkitgovrani</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pulkitgovrani"/>
    <language>en</language>
    <item>
      <title>How to Generate a Secure API Key or Secret (Length, Encoding, and Storage)</title>
      <dc:creator>pulkitgovrani</dc:creator>
      <pubDate>Thu, 15 Oct 2026 04:30:00 +0000</pubDate>
      <link>https://dev.to/pulkitgovrani/how-to-generate-a-secure-api-key-or-secret-length-encoding-and-storage-59mc</link>
      <guid>https://dev.to/pulkitgovrani/how-to-generate-a-secure-api-key-or-secret-length-encoding-and-storage-59mc</guid>
      <description>&lt;p&gt;API keys, session tokens, and signing secrets are all just random values that must be impossible to guess. Generating them well is straightforward, but a few common shortcuts, such as using a weak random function, undermine everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  How much randomness do you need?
&lt;/h2&gt;

&lt;p&gt;Aim for at least 128 bits of entropy, and 256 bits (32 random bytes) is a comfortable default for long-lived secrets. That is far beyond what can be brute-forced.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;16 bytes = 128 bits: 32 hex characters, or 22 base64url characters.&lt;/li&gt;
&lt;li&gt;32 bytes = 256 bits: 64 hex characters, or 43 base64url characters.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Use a cryptographically secure generator
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Never use Math.random() or similar for secrets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;General-purpose random functions are predictable. Use the operating system's cryptographically secure source through your language's standard library.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Node.js&lt;/span&gt;
&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Browser&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRandomValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Python&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;token_urlsafe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Shell&lt;/span&gt;
&lt;span class="nx"&gt;openssl&lt;/span&gt; &lt;span class="nx"&gt;rand&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;hex&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Encoding and format
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Hex is simple and safe everywhere but longer.&lt;/li&gt;
&lt;li&gt;Base64url packs more entropy per character and is safe in URLs and headers.&lt;/li&gt;
&lt;li&gt;A readable prefix (like sk_live_ or ghp_) helps people and scanners recognize a key and tell environments apart. The prefix isn't part of the secret's strength.&lt;/li&gt;
&lt;li&gt;Consider including a short key ID separate from the secret so you can look keys up without storing the secret itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Storing and handling keys
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Show the full key to the user only once, at creation.&lt;/li&gt;
&lt;li&gt;Store only a hash of the key on the server (a fast hash like SHA-256 is fine for high-entropy random keys, unlike passwords).&lt;/li&gt;
&lt;li&gt;Compare using a constant-time comparison to avoid timing leaks.&lt;/li&gt;
&lt;li&gt;Keep secrets out of source control, client-side code, and logs; use environment variables or a secrets manager.&lt;/li&gt;
&lt;li&gt;Support rotation and revocation: keys should be replaceable and expire when appropriate.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  If a key leaks
&lt;/h2&gt;

&lt;p&gt;Revoke it immediately, issue a new one, and review access logs for misuse. Removing it from a public repository after the fact doesn't un-leak it.&lt;/p&gt;

&lt;p&gt;When you generate keys with an online tool, choose one that creates them in your browser using the Web Crypto API so the value is never transmitted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How long should an API key be?
&lt;/h3&gt;

&lt;p&gt;At least 128 bits of randomness; 32 random bytes (256 bits) is a strong default.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Math.random() safe for generating secrets?
&lt;/h3&gt;

&lt;p&gt;No. Use a cryptographically secure generator such as crypto.randomBytes or crypto.getRandomValues.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I store API keys in plain text?
&lt;/h3&gt;

&lt;p&gt;No. Store only a hash of the key and show the full value once when it is created.&lt;/p&gt;

&lt;h3&gt;
  
  
  What should I do if an API key is exposed?
&lt;/h3&gt;

&lt;p&gt;Revoke and rotate it immediately, then check logs for unauthorized use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://password.ilovekit.app/secret" rel="noopener noreferrer"&gt;Secret/API Key Generator&lt;/a&gt; — free, runs in your browser, nothing is uploaded.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://ilovekit.app/blog/how-to-generate-a-secure-api-key" rel="noopener noreferrer"&gt;ilovekit.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>URL Encoding (Percent-Encoding) Explained: encodeURIComponent, Spaces, and Double Encoding</title>
      <dc:creator>pulkitgovrani</dc:creator>
      <pubDate>Wed, 14 Oct 2026 16:30:00 +0000</pubDate>
      <link>https://dev.to/pulkitgovrani/url-encoding-percent-encoding-explained-encodeuricomponent-spaces-and-double-encoding-22kl</link>
      <guid>https://dev.to/pulkitgovrani/url-encoding-percent-encoding-explained-encodeuricomponent-spaces-and-double-encoding-22kl</guid>
      <description>&lt;p&gt;URLs can only contain a limited set of characters. To include anything else, such as spaces, accented letters, or symbols with special meaning, they are converted to percent-encoding: a percent sign followed by two hexadecimal digits representing the byte.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Text is first converted to bytes using UTF-8, and each byte that isn't allowed is written as %XX. A space is the byte 0x20, so it becomes %20. The letter e with an acute accent takes two bytes in UTF-8, so it becomes %C3%A9.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hello world      -&amp;gt;  hello%20world
a&amp;amp;b=c            -&amp;gt;  a%26b%3Dc
café             -&amp;gt;  caf%C3%A9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reserved characters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Characters like : / ? # [ ] @ ! $ &amp;amp; ' ( ) * + , ; = have special roles in URLs.&lt;/li&gt;
&lt;li&gt;If you want one of them as data (for example, an ampersand inside a query value), it must be encoded so it isn't mistaken for structure.&lt;/li&gt;
&lt;li&gt;Unreserved characters (letters, digits, - . _ ~) never need encoding.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  encodeURI vs encodeURIComponent
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;encodeURI() encodes a whole URL and leaves structural characters like : / ? &amp;amp; = # alone.&lt;/li&gt;
&lt;li&gt;encodeURIComponent() encodes a single value and does encode those characters, which is what you want for a query parameter or path segment.&lt;/li&gt;
&lt;li&gt;Use encodeURIComponent for values you insert into a URL; using encodeURI on a value would leave &amp;amp; and = unescaped and can corrupt the query string.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cats &amp;amp; dogs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/search?q=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// /search?q=cats%20%26%20dogs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  %20 vs +
&lt;/h2&gt;

&lt;p&gt;In a query string produced by an HTML form (application/x-www-form-urlencoded), spaces are written as +. In other parts of a URL, and in most modern APIs, a space is %20. Decoders for form data treat + as a space, so a literal plus sign must be sent as %2B.&lt;/p&gt;

&lt;h2&gt;
  
  
  Double encoding and other pitfalls
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Double encoding: encoding an already-encoded string turns %20 into %2520. Encode raw values exactly once.&lt;/li&gt;
&lt;li&gt;Decode once as well; decoding twice can change meaning and is a source of security bugs.&lt;/li&gt;
&lt;li&gt;Encode the value, not the whole URL with its structure.&lt;/li&gt;
&lt;li&gt;Let your HTTP client or URL builder handle it when possible instead of concatenating strings.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Debugging&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a link breaks, paste the URL into an encoder/decoder to see the raw text. Do it locally if the URL contains tokens or personal data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is percent-encoding?
&lt;/h3&gt;

&lt;p&gt;A way to represent special or unsafe characters in URLs as a percent sign followed by two hex digits, such as %20 for a space.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between encodeURI and encodeURIComponent?
&lt;/h3&gt;

&lt;p&gt;encodeURI leaves URL structure characters intact, while encodeURIComponent encodes them, making it correct for individual parameter values.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is a space %20 or +?
&lt;/h3&gt;

&lt;p&gt;%20 works everywhere in URLs. The + form is used only in form-encoded query strings.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is double encoding?
&lt;/h3&gt;

&lt;p&gt;Encoding a value twice, turning %20 into %2520. It causes garbled data and should be avoided by encoding exactly once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://base64.ilovekit.app" rel="noopener noreferrer"&gt;Base64 &amp;amp; URL Encoder&lt;/a&gt; — free, runs in your browser, nothing is uploaded.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://ilovekit.app/blog/url-encoding-explained-percent-encoding" rel="noopener noreferrer"&gt;ilovekit.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>encoding</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Write a .gitignore File: Patterns, Examples, and Common Mistakes</title>
      <dc:creator>pulkitgovrani</dc:creator>
      <pubDate>Wed, 14 Oct 2026 04:30:00 +0000</pubDate>
      <link>https://dev.to/pulkitgovrani/how-to-write-a-gitignore-file-patterns-examples-and-common-mistakes-49ga</link>
      <guid>https://dev.to/pulkitgovrani/how-to-write-a-gitignore-file-patterns-examples-and-common-mistakes-49ga</guid>
      <description>&lt;p&gt;A .gitignore file tells Git which files and folders to leave untracked: build output, dependency folders, editor settings, and secrets. Getting it right early keeps your repository small and clean and helps prevent accidents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern syntax
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# Comments must be on their own line
&lt;/span&gt;
&lt;span class="c"&gt;# any .log file
&lt;/span&gt;*.&lt;span class="n"&gt;log&lt;/span&gt;

&lt;span class="c"&gt;# a directory named build, anywhere
&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;/

&lt;span class="c"&gt;# only dist in the repo root
&lt;/span&gt;/&lt;span class="n"&gt;dist&lt;/span&gt;

&lt;span class="c"&gt;# temp directories at any depth
&lt;/span&gt;**/&lt;span class="n"&gt;temp&lt;/span&gt;

&lt;span class="c"&gt;# negate: track this file even though *.log is ignored
&lt;/span&gt;!&lt;span class="n"&gt;important&lt;/span&gt;.&lt;span class="n"&gt;log&lt;/span&gt;

&lt;span class="c"&gt;# environment file with secrets
&lt;/span&gt;.&lt;span class="n"&gt;env&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;* matches anything except a slash; ** matches directories at any depth.&lt;/li&gt;
&lt;li&gt;A trailing slash matches only directories.&lt;/li&gt;
&lt;li&gt;A leading slash anchors the pattern to the repo root.&lt;/li&gt;
&lt;li&gt;A # starts a comment only at the beginning of a line; text after a pattern on the same line becomes part of the pattern.&lt;/li&gt;
&lt;li&gt;Patterns are evaluated top to bottom, and later rules can override earlier ones.&lt;/li&gt;
&lt;li&gt;You can't re-include a file if a parent directory is ignored.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to ignore
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Dependencies: node_modules/, vendor/, virtual environments.&lt;/li&gt;
&lt;li&gt;Build output: dist/, build/, .next/, target/, __pycache__/.&lt;/li&gt;
&lt;li&gt;Logs and temporary files: *.log, *.tmp.&lt;/li&gt;
&lt;li&gt;OS and editor files: .DS_Store, Thumbs.db, .idea/, .vscode/ (unless you share settings).&lt;/li&gt;
&lt;li&gt;Secrets and local config: .env, *.pem, credentials files.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  It doesn't work on files already tracked
&lt;/h2&gt;

&lt;p&gt;If a file was committed before you added it to .gitignore, Git keeps tracking it. Remove it from the index (not from disk) and commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;--cached&lt;/span&gt; path/to/file
git &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;--cached&lt;/span&gt; node_modules
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Stop tracking ignored files"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Secrets: prevention and cleanup
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ignoring a secret after committing it isn't enough&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once a secret is in Git history, it stays there and may already be copied elsewhere. Rotate the credential immediately, then remove it from history if needed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Useful extras
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A global ignore file (git config --global core.excludesfile ~/.gitignore_global) handles personal editor and OS files across all repos.&lt;/li&gt;
&lt;li&gt;git check-ignore -v path shows which rule is ignoring a file.&lt;/li&gt;
&lt;li&gt;Start from a template for your language or framework, then trim it.&lt;/li&gt;
&lt;li&gt;Commit a .env.example with placeholder values so others know which variables are needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why isn't my .gitignore working?
&lt;/h3&gt;

&lt;p&gt;The file is probably already tracked. Run git rm --cached on it, then commit; the ignore rule will apply afterwards.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I ignore a folder except one file?
&lt;/h3&gt;

&lt;p&gt;Ignore the folder's contents with folder/* (not the folder itself), then add a negation like !folder/keep.txt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I commit .env files?
&lt;/h3&gt;

&lt;p&gt;No. Commit a .env.example with dummy values and keep the real .env ignored.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a global gitignore?
&lt;/h3&gt;

&lt;p&gt;A personal ignore file that applies to all your repositories, useful for editor and OS files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://dev.ilovekit.app/gitignore" rel="noopener noreferrer"&gt;.gitignore Generator&lt;/a&gt; — free, runs in your browser, nothing is uploaded.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://ilovekit.app/blog/how-to-write-a-gitignore-file" rel="noopener noreferrer"&gt;ilovekit.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>developer</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>UUID Versions Explained: v1, v4, v5, v7 and Which One to Use</title>
      <dc:creator>pulkitgovrani</dc:creator>
      <pubDate>Tue, 13 Oct 2026 16:30:00 +0000</pubDate>
      <link>https://dev.to/pulkitgovrani/uuid-versions-explained-v1-v4-v5-v7-and-which-one-to-use-5gdi</link>
      <guid>https://dev.to/pulkitgovrani/uuid-versions-explained-v1-v4-v5-v7-and-which-one-to-use-5gdi</guid>
      <description>&lt;p&gt;A UUID (universally unique identifier) is a 128-bit value used to identify things without a central authority handing out numbers. It's written as 32 hexadecimal digits in five groups, like 3f2b8c1e-9a4d-4c7e-8f01-2b6d5e7a9c10.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading a UUID
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The layout is 8-4-4-4-12 hex digits.&lt;/li&gt;
&lt;li&gt;The first digit of the third group is the version. In 3f2b8c1e-9a4d-4c7e-..., the 4 marks version 4.&lt;/li&gt;
&lt;li&gt;The first digit of the fourth group encodes the variant (usually 8, 9, a, or b for standard UUIDs).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The main versions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;v1: based on a timestamp and the machine's MAC address. Sortable-ish, but it can leak the machine and creation time.&lt;/li&gt;
&lt;li&gt;v3 and v5: name-based; hash a namespace plus a name (v3 with MD5, v5 with SHA-1) to get the same UUID every time for the same input.&lt;/li&gt;
&lt;li&gt;v4: random. The most common; 122 of its 128 bits are random.&lt;/li&gt;
&lt;li&gt;v6 and v7: time-ordered versions standardized in RFC 9562 (2024). v7 puts a millisecond timestamp first followed by random bits.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Will two UUIDs ever collide?
&lt;/h2&gt;

&lt;p&gt;With v4 there are 2^122, about 5.3 x 10^36, possible values. Even generating a billion UUIDs, the chance of any collision is on the order of 10^-19, so for practical purposes collisions are not a concern when a good random source is used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why v7 is nice for databases
&lt;/h2&gt;

&lt;p&gt;Random v4 keys land all over a B-tree index, which causes page splits and poorer cache locality on large tables. Time-ordered UUIDs (v7) are roughly sequential, so inserts append near the end of the index, like an auto-increment key, while still being globally unique and generated without coordination.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which should you use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;General unique IDs: v4 is simple and universally supported.&lt;/li&gt;
&lt;li&gt;Primary keys in large databases: consider v7 for better index behavior.&lt;/li&gt;
&lt;li&gt;Deterministic IDs from a name: v5.&lt;/li&gt;
&lt;li&gt;Avoid v1 if you don't want to expose timing or machine details.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A UUID is not a secret&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;UUIDs are identifiers, not authorization tokens. Don't rely on them being hard to guess as your only access control; use proper authentication, and generate secrets with a cryptographic random generator.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a UUID?
&lt;/h3&gt;

&lt;p&gt;A 128-bit identifier written as 32 hex digits in the 8-4-4-4-12 format, designed to be unique without central coordination.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can two UUIDs be the same?
&lt;/h3&gt;

&lt;p&gt;In theory yes, but with random v4 UUIDs the probability is so small it is negligible in practice.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between UUID v4 and v7?
&lt;/h3&gt;

&lt;p&gt;v4 is entirely random. v7 begins with a timestamp, so values sort roughly by creation time, which is better for database indexes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are UUIDs safe to use as security tokens?
&lt;/h3&gt;

&lt;p&gt;Not by themselves. Use a cryptographically secure random token for secrets and proper access control for resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://dev.ilovekit.app" rel="noopener noreferrer"&gt;UUID Generator&lt;/a&gt; — free, runs in your browser, nothing is uploaded.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://ilovekit.app/blog/uuid-versions-explained" rel="noopener noreferrer"&gt;ilovekit.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>developer</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>HTTP Status Codes Cheatsheet: What 200, 301, 404, 500 and the Rest Mean</title>
      <dc:creator>pulkitgovrani</dc:creator>
      <pubDate>Tue, 13 Oct 2026 04:30:00 +0000</pubDate>
      <link>https://dev.to/pulkitgovrani/http-status-codes-cheatsheet-what-200-301-404-500-and-the-rest-mean-2l4m</link>
      <guid>https://dev.to/pulkitgovrani/http-status-codes-cheatsheet-what-200-301-404-500-and-the-rest-mean-2l4m</guid>
      <description>&lt;p&gt;Every HTTP response starts with a three-digit status code that tells the client what happened. Learning the five classes gives you most of the picture, and a couple of dozen specific codes cover nearly everything you'll see.&lt;/p&gt;

&lt;h2&gt;
  
  
  The five classes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;1xx Informational: the request was received and processing continues (rarely seen directly).&lt;/li&gt;
&lt;li&gt;2xx Success: the request worked.&lt;/li&gt;
&lt;li&gt;3xx Redirection: the client needs to take another step, usually going to a different URL.&lt;/li&gt;
&lt;li&gt;4xx Client error: something is wrong with the request.&lt;/li&gt;
&lt;li&gt;5xx Server error: the server failed to handle a valid request.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Success codes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;200 OK: standard success.&lt;/li&gt;
&lt;li&gt;201 Created: a new resource was created (typical for POST).&lt;/li&gt;
&lt;li&gt;202 Accepted: the request was accepted but processing isn't finished.&lt;/li&gt;
&lt;li&gt;204 No Content: success with no body, common for DELETE and some PUTs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Redirects
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;301 Moved Permanently: the resource has a new permanent URL; search engines transfer ranking.&lt;/li&gt;
&lt;li&gt;302 Found: a temporary redirect.&lt;/li&gt;
&lt;li&gt;307 Temporary Redirect and 308 Permanent Redirect: like 302 and 301, but the request method and body are preserved.&lt;/li&gt;
&lt;li&gt;304 Not Modified: the cached copy is still valid.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Client errors
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;400 Bad Request: malformed or invalid request.&lt;/li&gt;
&lt;li&gt;401 Unauthorized: authentication is missing or invalid (despite the name, it means unauthenticated).&lt;/li&gt;
&lt;li&gt;403 Forbidden: you are identified but not allowed.&lt;/li&gt;
&lt;li&gt;404 Not Found: nothing exists at that URL.&lt;/li&gt;
&lt;li&gt;405 Method Not Allowed: the path exists but not for that method.&lt;/li&gt;
&lt;li&gt;409 Conflict: the request conflicts with the current state, such as a duplicate.&lt;/li&gt;
&lt;li&gt;410 Gone: the resource was intentionally removed permanently.&lt;/li&gt;
&lt;li&gt;422 Unprocessable Content: the request was well-formed but failed validation.&lt;/li&gt;
&lt;li&gt;429 Too Many Requests: you're being rate limited; check the Retry-After header.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Server errors
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;500 Internal Server Error: an unexpected failure on the server.&lt;/li&gt;
&lt;li&gt;502 Bad Gateway: a proxy or gateway received an invalid response from upstream.&lt;/li&gt;
&lt;li&gt;503 Service Unavailable: temporarily overloaded or down for maintenance.&lt;/li&gt;
&lt;li&gt;504 Gateway Timeout: an upstream server didn't respond in time.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;401 vs 403&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use 401 when the caller hasn't proven who they are (log in or send a valid token). Use 403 when they are known but don't have permission for that resource.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is the difference between 301 and 302?
&lt;/h3&gt;

&lt;p&gt;301 is a permanent redirect and passes SEO value to the new URL. 302 is temporary, so search engines keep the original URL.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does a 500 error mean?
&lt;/h3&gt;

&lt;p&gt;The server hit an unexpected problem. It is a server-side issue, not something the client did wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between 401 and 403?
&lt;/h3&gt;

&lt;p&gt;401 means authentication is missing or invalid. 403 means you're authenticated but not permitted.&lt;/p&gt;

&lt;h3&gt;
  
  
  What should I do when I get a 429?
&lt;/h3&gt;

&lt;p&gt;Slow down and retry after the delay in the Retry-After header, using exponential backoff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://dev.ilovekit.app/http" rel="noopener noreferrer"&gt;HTTP Status Code Lookup&lt;/a&gt; — free, runs in your browser, nothing is uploaded.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://ilovekit.app/blog/http-status-codes-cheatsheet" rel="noopener noreferrer"&gt;ilovekit.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>developer</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Compound Interest Explained: The Formula, the Rule of 72, and Why Time Matters</title>
      <dc:creator>pulkitgovrani</dc:creator>
      <pubDate>Mon, 12 Oct 2026 16:30:00 +0000</pubDate>
      <link>https://dev.to/pulkitgovrani/compound-interest-explained-the-formula-the-rule-of-72-and-why-time-matters-2ofn</link>
      <guid>https://dev.to/pulkitgovrani/compound-interest-explained-the-formula-the-rule-of-72-and-why-time-matters-2ofn</guid>
      <description>&lt;p&gt;Simple interest is paid only on the original amount. Compound interest is paid on the original amount plus the interest already earned, so the growth builds on itself. Over long periods the difference is dramatic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The formulas
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Simple:    A = P x (1 + r x t)
Compound:  A = P x (1 + r/n)^(n x t)

P = starting amount   r = annual rate (as a decimal)
t = years             n = compounding periods per year
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A worked example
&lt;/h2&gt;

&lt;p&gt;Invest 10,000 at 7% per year for 20 years:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple interest: 10,000 x (1 + 0.07 x 20) = 24,000.&lt;/li&gt;
&lt;li&gt;Compounded annually: 10,000 x 1.07^20 = about 38,697.&lt;/li&gt;
&lt;li&gt;Compounded monthly: 10,000 x (1 + 0.07/12)^240 = about 40,387.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difference between simple and compound is almost 15,000 on the same rate and time, entirely from earning interest on interest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compounding frequency
&lt;/h2&gt;

&lt;p&gt;The more often interest compounds (annually, monthly, daily), the more you earn, but the gains from increasing frequency shrink quickly. Moving from annual to monthly matters more than going from monthly to daily.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule of 72
&lt;/h2&gt;

&lt;p&gt;To estimate how long money takes to double, divide 72 by the annual rate in percent. At 6%, 72 / 6 = 12 years (the exact figure is about 11.9). It is a handy mental shortcut that works best for rates between about 4% and 12%.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means in practice
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Starting early matters more than starting big; time is the main ingredient.&lt;/li&gt;
&lt;li&gt;Regular contributions add fresh principal that also compounds.&lt;/li&gt;
&lt;li&gt;The same math works against you on debt: credit card balances compound too.&lt;/li&gt;
&lt;li&gt;Fees and taxes reduce the effective rate, so compare after-cost returns.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Illustration, not a forecast&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Real returns vary and are never guaranteed, and this is not financial advice. Use the formula to understand the mechanics, not to predict outcomes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is the compound interest formula?
&lt;/h3&gt;

&lt;p&gt;A = P(1 + r/n)^(nt), where P is principal, r the annual rate, n compounding periods per year, and t years.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between simple and compound interest?
&lt;/h3&gt;

&lt;p&gt;Simple interest is calculated only on the principal. Compound interest is calculated on the principal plus accumulated interest.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the rule of 72?
&lt;/h3&gt;

&lt;p&gt;A shortcut: divide 72 by the annual interest rate to estimate the years needed to double your money.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does compounding more often earn more?
&lt;/h3&gt;

&lt;p&gt;Yes, but with diminishing returns; the jump from annual to monthly is larger than from monthly to daily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://calc.ilovekit.app/interest" rel="noopener noreferrer"&gt;Simple &amp;amp; Compound Interest&lt;/a&gt; — free, runs in your browser, nothing is uploaded.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://ilovekit.app/blog/compound-interest-explained" rel="noopener noreferrer"&gt;ilovekit.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>calculators</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How Loan EMI Is Calculated: The Formula, a Worked Example, and How to Reduce It</title>
      <dc:creator>pulkitgovrani</dc:creator>
      <pubDate>Mon, 12 Oct 2026 04:30:00 +0000</pubDate>
      <link>https://dev.to/pulkitgovrani/how-loan-emi-is-calculated-the-formula-a-worked-example-and-how-to-reduce-it-3o8p</link>
      <guid>https://dev.to/pulkitgovrani/how-loan-emi-is-calculated-the-formula-a-worked-example-and-how-to-reduce-it-3o8p</guid>
      <description>&lt;p&gt;An EMI (equated monthly installment) is the fixed amount you pay every month to repay a loan. Each payment covers the interest for the month plus part of the principal. Early on, most of the payment is interest; later, most of it is principal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The formula
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EMI = P x r x (1 + r)^n / ((1 + r)^n - 1)

P = loan amount (principal)
r = monthly interest rate = annual rate / 12 / 100
n = number of monthly installments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A worked example
&lt;/h2&gt;

&lt;p&gt;Borrow 1,000,000 at 9% per year for 5 years. Here r = 9 / 12 / 100 = 0.0075 and n = 60. Plugging these into the formula gives an EMI of about 20,758.36 per month.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total paid: 20,758.36 x 60 = about 1,245,501.&lt;/li&gt;
&lt;li&gt;Total interest: about 245,501 on a 1,000,000 loan.&lt;/li&gt;
&lt;li&gt;The same loan over 10 years gives an EMI of about 12,668 but total interest of about 520,109.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What changes the EMI
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Loan amount: the EMI scales in proportion to the principal.&lt;/li&gt;
&lt;li&gt;Interest rate: even a one-point difference adds up over the years.&lt;/li&gt;
&lt;li&gt;Tenure: longer means a lower EMI but much more total interest, as the 5-year versus 10-year example shows.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ways to reduce the interest you pay
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Make a larger down payment so you borrow less.&lt;/li&gt;
&lt;li&gt;Choose the shortest tenure whose EMI you can comfortably afford.&lt;/li&gt;
&lt;li&gt;Make part-prepayments; they reduce the outstanding principal, cutting interest, and you can choose to shorten the tenure or lower the EMI.&lt;/li&gt;
&lt;li&gt;Compare rates and fees across lenders, and check whether floating rates can be reset.&lt;/li&gt;
&lt;li&gt;Check for prepayment charges before committing.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Educational only&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This explains the standard reducing-balance formula. Actual loans may include processing fees, insurance, or different compounding, so use your lender's schedule for exact numbers. This is not financial advice.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is the formula for EMI?
&lt;/h3&gt;

&lt;p&gt;EMI = P x r x (1 + r)^n / ((1 + r)^n - 1), where P is the principal, r the monthly rate, and n the number of months.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does a longer tenure reduce total cost?
&lt;/h3&gt;

&lt;p&gt;No. It lowers the monthly payment but increases the total interest paid.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does prepayment help?
&lt;/h3&gt;

&lt;p&gt;It reduces the outstanding principal, so less interest accrues. You can use it to shorten the loan or lower the EMI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is EMI the same for the whole loan?
&lt;/h3&gt;

&lt;p&gt;For a fixed-rate loan, yes. The split between interest and principal changes each month, but the total stays the same.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://calc.ilovekit.app/emi" rel="noopener noreferrer"&gt;Loan EMI Calculator&lt;/a&gt; — free, runs in your browser, nothing is uploaded.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://ilovekit.app/blog/how-emi-is-calculated" rel="noopener noreferrer"&gt;ilovekit.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>calculators</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>FrostLine: A Garden Planner Powered by a Local Open-Source LLM</title>
      <dc:creator>pulkitgovrani</dc:creator>
      <pubDate>Sun, 11 Oct 2026 18:34:56 +0000</pubDate>
      <link>https://dev.to/pulkitgovrani/frostline-a-garden-planner-powered-by-a-local-open-source-llm-45il</link>
      <guid>https://dev.to/pulkitgovrani/frostline-a-garden-planner-powered-by-a-local-open-source-llm-45il</guid>
      <description>&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;FrostLine tells you what to do in the garden &lt;strong&gt;this week&lt;/strong&gt;. You type your town. It pulls 15 years of nightly lows, works out your median and 1-in-10 "safe" last spring frost and first fall frost, and lists what to sow, start indoors or transplant right now, plus tonight's frost risk.&lt;/p&gt;

&lt;p&gt;A local LLM then turns the plan into a short field note that always ends the same way: put the phone down and go outside.&lt;/p&gt;

&lt;p&gt;It is for anyone with a patch of soil, a balcony or an allotment who is tired of generic "plant in spring" advice. It also works in places that never freeze: I tested Pune and Sydney, where it switches to the local cool/warm cycle instead of frost dates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/cRSjsBCFWN8" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Live: &lt;a href="https://frostline-h8z9.onrender.com" rel="noopener noreferrer"&gt;frostline-h8z9.onrender.com&lt;/a&gt;. It runs on Render's free tier, so the first load can take about 50 seconds to wake up. The hosted version has no Ollama, so its field note comes from a template; the local LLM version is the one in the video.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pulkitgovrani" rel="noopener noreferrer"&gt;
        pulkitgovrani
      &lt;/a&gt; / &lt;a href="https://github.com/pulkitgovrani/frostline" rel="noopener noreferrer"&gt;
        frostline
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Garden jobs from your town's frost history, narrated by a local open-weight LLM
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;FrostLine&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Live demo: &lt;a href="https://frostline-h8z9.onrender.com" rel="nofollow noopener noreferrer"&gt;https://frostline-h8z9.onrender.com&lt;/a&gt; (free tier, first load may take ~50s; no local LLM there, so the note is templated)&lt;/p&gt;
&lt;p&gt;This week's garden jobs, computed from your own town's frost history, with a local open-weight LLM writing the field note
Weather history is fetched once (Open-Meteo, no key) and cached in &lt;code&gt;data/&lt;/code&gt;, so afterwards it works without signal.&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;python3 -m venv .venv &lt;span class="pl-k"&gt;&amp;amp;&amp;amp;&lt;/span&gt; .venv/bin/pip install -r requirements.txt
ollama pull gemma4:e4b            &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; any Ollama model works: FROSTLINE_MODEL=llama3.2 ...&lt;/span&gt;
.venv/bin/python -m frostline.cli &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;Minneapolis&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;          &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; CLI&lt;/span&gt;
.venv/bin/python -m frostline 8765                       &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; web UI on http://localhost:8765&lt;/span&gt;
.venv/bin/python -m pytest -q&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;climate.py&lt;/code&gt;: 15 years of daily minimum temperature -&amp;gt; median and 1-in-10 safe last-spring / first-fall frost dates (hemisphere-aware).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;planner.py&lt;/code&gt;: transparent rules for ~17 crops anchored on those dates. Tender crops wait for the &lt;em&gt;safe&lt;/em&gt; date. Frost-free climates use the local cool/warm cycle instead.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;model.py&lt;/code&gt;: tonight's…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/pulkitgovrani/frostline" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open-weight LLM, running locally:&lt;/strong&gt; Gemma (&lt;code&gt;gemma4:e4b&lt;/code&gt;) through Ollama. The LLM only narrates. Planting dates come from code, because small models invent dates. I caught mine inventing chores (compost, gloves) when the plan was empty, so empty weeks now skip the LLM and use a template.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rules, not vibes:&lt;/strong&gt; &lt;code&gt;planner.py&lt;/code&gt; anchors about 17 crops on the frost dates. Tender crops wait for the 1-in-10 safe date; hardy ones use the median.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frost model:&lt;/strong&gt; a gradient-boosting classifier predicts tonight's frost from day of year, latitude and recent lows. On two held-out years it scored a Brier of 0.054 against 0.068 for a plain day-of-year baseline (Minneapolis), so it does beat climatology. If you set a &lt;code&gt;TABPFN_TOKEN&lt;/code&gt;, it can use TabPFN instead; I have not run that path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data:&lt;/strong&gt; Open-Meteo history is fetched once and cached on disk, so after the first run for a town it works with no signal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stack:&lt;/strong&gt; plain Python, pandas, scikit-learn and the standard-library HTTP server, with a single static page for the UI. Tests cover the planner and the frost model.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It works where gardens are:&lt;/strong&gt; the garden has no wifi. The weights and the cached data live on the device, which a closed API cannot offer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your location stays yours:&lt;/strong&gt; your town and your garden never reach a server I don't control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappable:&lt;/strong&gt; &lt;code&gt;FROSTLINE_MODEL=llama3.2&lt;/code&gt; changes the narrator with no code change, and the frost model can swap sklearn for TabPFN.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free to run:&lt;/strong&gt; no API bill for a weekend hobby.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render:&lt;/strong&gt; the web UI is hosted on Render as a free web service, deployed from a &lt;code&gt;render.yaml&lt;/code&gt; Blueprint in the repo.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>python</category>
    </item>
    <item>
      <title>Binary, Octal, Decimal, and Hexadecimal Explained (With Conversion Methods)</title>
      <dc:creator>pulkitgovrani</dc:creator>
      <pubDate>Sun, 11 Oct 2026 16:30:00 +0000</pubDate>
      <link>https://dev.to/pulkitgovrani/binary-octal-decimal-and-hexadecimal-explained-with-conversion-methods-4b52</link>
      <guid>https://dev.to/pulkitgovrani/binary-octal-decimal-and-hexadecimal-explained-with-conversion-methods-4b52</guid>
      <description>&lt;p&gt;We write numbers in base 10 because we have ten fingers. Computers work in base 2, and programmers often use base 8 and base 16 as compact ways to write binary. Once you see the pattern, conversions become straightforward.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a base means
&lt;/h2&gt;

&lt;p&gt;In any base, each digit position is worth a power of the base. In decimal, 345 means 3 x 100 + 4 x 10 + 5 x 1. In binary, each position is a power of 2, so 1101 means 1 x 8 + 1 x 4 + 0 x 2 + 1 x 1, which is 13.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four common bases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Binary (base 2): digits 0 and 1. How hardware stores everything.&lt;/li&gt;
&lt;li&gt;Octal (base 8): digits 0 to 7. Used for Unix file permissions (chmod 755).&lt;/li&gt;
&lt;li&gt;Decimal (base 10): digits 0 to 9. Everyday numbers.&lt;/li&gt;
&lt;li&gt;Hexadecimal (base 16): digits 0 to 9 and A to F. Colors, memory addresses, and byte values.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Decimal  Binary     Octal  Hex
10       1010       12     A
255      11111111   377    FF
4095     111111111111  7777  FFF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Converting decimal to another base
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Divide the number by the target base and record the remainder.&lt;/li&gt;
&lt;li&gt;Divide the quotient again, repeating until the quotient is 0.&lt;/li&gt;
&lt;li&gt;Read the remainders from last to first.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example: 255 in hex. 255 divided by 16 is 15 remainder 15, and 15 divided by 16 is 0 remainder 15. Both remainders are F, so 255 is FF.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why hex is so common
&lt;/h2&gt;

&lt;p&gt;One hex digit represents exactly four bits, so one byte is always two hex digits. That is why colors are written like #4338ca, and why 0xFF is 255, the largest value of a single byte. Converting between binary and hex is just grouping bits in fours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prefixes in code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;0b1010 for binary, 0o12 for octal (or a leading 0 in some older languages), and 0xFF for hex.&lt;/li&gt;
&lt;li&gt;In JavaScript, parseInt('ff', 16) parses hex and (255).toString(2) gives binary.&lt;/li&gt;
&lt;li&gt;In Python, int('ff', 16), bin(255), oct(255), and hex(255) do the conversions.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Negative numbers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Computers usually store negative integers in two's complement form, so the same bits can mean different values depending on whether the number is signed. Check the type when converting negative values.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How do I convert binary to decimal?
&lt;/h3&gt;

&lt;p&gt;Add up the powers of 2 for each 1 bit. 1101 is 8 + 4 + 1 = 13.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do programmers use hexadecimal?
&lt;/h3&gt;

&lt;p&gt;Each hex digit maps to four bits, making binary values compact and easy to read.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is 255 in binary and hex?
&lt;/h3&gt;

&lt;p&gt;255 is 11111111 in binary and FF in hexadecimal.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does chmod 755 mean?
&lt;/h3&gt;

&lt;p&gt;It is an octal permission value: 7 (read, write, execute) for the owner, and 5 (read, execute) for group and others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://convert.ilovekit.app/base" rel="noopener noreferrer"&gt;Number Base Converter&lt;/a&gt; — free, runs in your browser, nothing is uploaded.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://ilovekit.app/blog/binary-octal-decimal-hexadecimal-explained" rel="noopener noreferrer"&gt;ilovekit.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>convert</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Time Zone Conversion: 7 Mistakes That Break Schedules and Timestamps</title>
      <dc:creator>pulkitgovrani</dc:creator>
      <pubDate>Sun, 11 Oct 2026 04:30:00 +0000</pubDate>
      <link>https://dev.to/pulkitgovrani/time-zone-conversion-7-mistakes-that-break-schedules-and-timestamps-32cm</link>
      <guid>https://dev.to/pulkitgovrani/time-zone-conversion-7-mistakes-that-break-schedules-and-timestamps-32cm</guid>
      <description>&lt;p&gt;Time zones are a classic source of bugs: meetings scheduled an hour off, reports that miss a day, jobs that run twice. Most of the pain comes from a small set of avoidable mistakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Storing local times without a zone
&lt;/h2&gt;

&lt;p&gt;A value like 2026-03-08 02:30 is ambiguous. Store instants in UTC (or as an ISO 8601 string with an offset, such as 2026-03-08T02:30:00Z) and convert to local time only when displaying it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Using abbreviations
&lt;/h2&gt;

&lt;p&gt;CST can mean Central Standard Time, China Standard Time, or Cuba Standard Time. IST can be India, Ireland, or Israel. Use IANA names such as America/Chicago, Asia/Kolkata, or Europe/London, which are unambiguous and carry the daylight saving rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Confusing offsets with zones
&lt;/h2&gt;

&lt;p&gt;An offset like UTC-5 is a fixed number. A zone like America/New_York is a set of rules that changes between UTC-5 and UTC-4 during the year. Recurring events need a zone, not just an offset.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Ignoring daylight saving transitions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When clocks spring forward, a local hour doesn't exist (2:30 AM may be skipped).&lt;/li&gt;
&lt;li&gt;When clocks fall back, a local hour happens twice, so a local time can map to two different instants.&lt;/li&gt;
&lt;li&gt;Not all places observe DST, and the rules change by government decision.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Assuming whole-hour offsets
&lt;/h2&gt;

&lt;p&gt;India is UTC+5:30, Nepal is UTC+5:45, and some regions use half-hour offsets. Code that assumes whole hours will be wrong for millions of people.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Adding 24 hours to mean 'tomorrow'
&lt;/h2&gt;

&lt;p&gt;On a DST change a local day can be 23 or 25 hours long. Use a date library to add calendar days in a specific zone.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Scheduling recurring meetings in UTC
&lt;/h2&gt;

&lt;p&gt;A meeting at 09:00 in New York stays at 09:00 local all year, which is a different UTC time in summer and winter. Store the zone and local time for recurring events.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Rules of thumb&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Store UTC, store IANA zone names when the local time matters, convert at the edges, and use a maintained library instead of hand-written offset math.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is the best way to store dates and times?
&lt;/h3&gt;

&lt;p&gt;Store instants in UTC (or ISO 8601 with an offset) and convert to the user's time zone only when displaying.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why shouldn't I use EST or IST?
&lt;/h3&gt;

&lt;p&gt;Abbreviations are ambiguous and don't encode daylight saving rules. Use IANA zone names like America/New_York.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I convert between time zones?
&lt;/h3&gt;

&lt;p&gt;Convert the local time to a UTC instant using the source zone's rules, then express that instant in the target zone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which time zones use half-hour offsets?
&lt;/h3&gt;

&lt;p&gt;Examples include India (UTC+5:30), and Nepal uses UTC+5:45.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://timestamp.ilovekit.app/timezone" rel="noopener noreferrer"&gt;Timezone Converter&lt;/a&gt; — free, runs in your browser, nothing is uploaded.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://ilovekit.app/blog/time-zone-conversion-mistakes-to-avoid" rel="noopener noreferrer"&gt;ilovekit.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>time</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>bcrypt vs Argon2: How to Hash Passwords Properly</title>
      <dc:creator>pulkitgovrani</dc:creator>
      <pubDate>Sat, 10 Oct 2026 16:30:00 +0000</pubDate>
      <link>https://dev.to/pulkitgovrani/bcrypt-vs-argon2-how-to-hash-passwords-properly-2efg</link>
      <guid>https://dev.to/pulkitgovrani/bcrypt-vs-argon2-how-to-hash-passwords-properly-2efg</guid>
      <description>&lt;p&gt;Storing passwords safely is one of the few areas where doing the standard thing well matters more than being clever. The standard thing is to use a purpose-built, deliberately slow password hashing function, and never a general-purpose hash such as MD5 or SHA-256 by itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a password hash needs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Slow by design: hashing should cost enough that guessing billions of passwords is impractical.&lt;/li&gt;
&lt;li&gt;Salted: a unique random value per password, so identical passwords hash differently and precomputed tables are useless.&lt;/li&gt;
&lt;li&gt;Tunable: a work factor you can raise as hardware improves.&lt;/li&gt;
&lt;li&gt;Memory-hard (ideally): making GPU and ASIC attacks more expensive.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  bcrypt
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Around since 1999 and available in essentially every language.&lt;/li&gt;
&lt;li&gt;Controlled by a cost factor: each increase of 1 doubles the work. OWASP suggests a cost of at least 10, and many teams use 12 or more, tuned so a hash takes a noticeable fraction of a second on your server.&lt;/li&gt;
&lt;li&gt;Only the first 72 bytes of the password are used, so very long passwords or passphrases are truncated. Some libraries pre-hash to handle this.&lt;/li&gt;
&lt;li&gt;Not memory-hard, which makes it somewhat easier to attack with specialized hardware.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Argon2id
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Winner of the Password Hashing Competition in 2015; Argon2id is the recommended variant.&lt;/li&gt;
&lt;li&gt;Has three parameters: memory, iterations (time), and parallelism.&lt;/li&gt;
&lt;li&gt;OWASP's minimum configuration is roughly 19 MiB of memory, 2 iterations, and 1 degree of parallelism, with other combinations offering similar strength.&lt;/li&gt;
&lt;li&gt;Memory-hardness makes large-scale cracking substantially more expensive.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Which should you choose?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Practical guidance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For new systems, use Argon2id if your platform has a well-maintained library. If not, bcrypt with a sensible cost remains a solid, widely supported choice. Either is vastly better than MD5, SHA-1, or plain SHA-256.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Good practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Use the library's built-in salt handling; never invent your own scheme.&lt;/li&gt;
&lt;li&gt;Store the full output string (it embeds the algorithm, parameters, and salt).&lt;/li&gt;
&lt;li&gt;Benchmark on production hardware and pick parameters that take roughly 100 to 500 milliseconds.&lt;/li&gt;
&lt;li&gt;Rehash on login when parameters are outdated, upgrading users gradually.&lt;/li&gt;
&lt;li&gt;Add rate limiting and multi-factor authentication; hashing doesn't stop online guessing.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is bcrypt still secure?
&lt;/h3&gt;

&lt;p&gt;Yes, with a sufficient cost factor it remains secure and widely used, though Argon2id is preferred for new designs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why not just use SHA-256 for passwords?
&lt;/h3&gt;

&lt;p&gt;It is designed to be fast, which lets attackers test billions of guesses per second. Password hashes are deliberately slow.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a salt?
&lt;/h3&gt;

&lt;p&gt;A unique random value added to each password before hashing so identical passwords produce different hashes.&lt;/p&gt;

&lt;h3&gt;
  
  
  What bcrypt cost factor should I use?
&lt;/h3&gt;

&lt;p&gt;At least 10, and commonly 12 or higher, tuned to take a noticeable fraction of a second on your hardware.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://hash.ilovekit.app/bcrypt" rel="noopener noreferrer"&gt;Bcrypt Hash Generator/Checker&lt;/a&gt; — free, runs in your browser, nothing is uploaded.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://ilovekit.app/blog/bcrypt-vs-argon2-password-hashing" rel="noopener noreferrer"&gt;ilovekit.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Verify a File Checksum (SHA-256) on Windows, macOS, and Linux</title>
      <dc:creator>pulkitgovrani</dc:creator>
      <pubDate>Sat, 10 Oct 2026 04:30:00 +0000</pubDate>
      <link>https://dev.to/pulkitgovrani/how-to-verify-a-file-checksum-sha-256-on-windows-macos-and-linux-1io0</link>
      <guid>https://dev.to/pulkitgovrani/how-to-verify-a-file-checksum-sha-256-on-windows-macos-and-linux-1io0</guid>
      <description>&lt;p&gt;Software downloads often list a checksum, a short string computed from the file's contents. If you compute the same checksum on your copy and it matches, the file is intact. If it doesn't, the download is corrupt or the file was changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a checksum proves (and doesn't)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A match shows your file is identical to the one the checksum was computed from.&lt;/li&gt;
&lt;li&gt;It protects against corruption and accidental changes.&lt;/li&gt;
&lt;li&gt;It only protects against tampering if the checksum itself came from a trustworthy source, ideally a different channel than the file, such as the vendor's HTTPS page or a signed release.&lt;/li&gt;
&lt;li&gt;If an attacker can replace both the file and the checksum on the same site, a match proves nothing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Compute a SHA-256 hash
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# macOS&lt;/span&gt;
shasum &lt;span class="nt"&gt;-a&lt;/span&gt; 256 file.iso

&lt;span class="c"&gt;# Linux&lt;/span&gt;
&lt;span class="nb"&gt;sha256sum &lt;/span&gt;file.iso

&lt;span class="c"&gt;# Windows (Command Prompt)&lt;/span&gt;
certutil &lt;span class="nt"&gt;-hashfile&lt;/span&gt; file.iso SHA256

&lt;span class="c"&gt;# Windows (PowerShell)&lt;/span&gt;
Get-FileHash file.iso &lt;span class="nt"&gt;-Algorithm&lt;/span&gt; SHA256
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Compare the result
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Copy the checksum published by the vendor.&lt;/li&gt;
&lt;li&gt;Run the command above on your downloaded file.&lt;/li&gt;
&lt;li&gt;Compare the two values character by character; hex case doesn't matter, but every digit does.&lt;/li&gt;
&lt;li&gt;Or paste both into a verifier tool that reports match or mismatch for you.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  If it doesn't match
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Re-download the file; interrupted or flaky downloads are the usual cause.&lt;/li&gt;
&lt;li&gt;Make sure you compared the right algorithm (SHA-256 vs SHA-1 vs MD5) and the right file version.&lt;/li&gt;
&lt;li&gt;Check you didn't copy extra whitespace.&lt;/li&gt;
&lt;li&gt;If it still fails, don't run the file; get it from an official source again.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hash locally&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hashing a large file in your browser doesn't upload it anywhere, so you can check installers and private documents without exposing them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a file checksum?
&lt;/h3&gt;

&lt;p&gt;A short fingerprint computed from a file's contents. Any change to the file produces a different checksum.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which algorithm should I use to verify downloads?
&lt;/h3&gt;

&lt;p&gt;SHA-256 is the common standard. Use whichever algorithm the publisher lists.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does a matching checksum mean the file is safe?
&lt;/h3&gt;

&lt;p&gt;It means it matches the published one. It is only as trustworthy as the source of the checksum.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I check a SHA-256 hash on Windows?
&lt;/h3&gt;

&lt;p&gt;Run Get-FileHash file -Algorithm SHA256 in PowerShell, or certutil -hashfile file SHA256 in Command Prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://hash.ilovekit.app/checksum" rel="noopener noreferrer"&gt;Checksum Verifier&lt;/a&gt; — free, runs in your browser, nothing is uploaded.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://ilovekit.app/blog/how-to-verify-a-file-checksum" rel="noopener noreferrer"&gt;ilovekit.app&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
