<?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: GREG T</title>
    <description>The latest articles on DEV Community by GREG T (@greg_t_7a8f861459a265bb67).</description>
    <link>https://dev.to/greg_t_7a8f861459a265bb67</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%2F4110670%2Fc2940c00-963c-4474-a8ee-c9ea42145a8b.jpg</url>
      <title>DEV Community: GREG T</title>
      <link>https://dev.to/greg_t_7a8f861459a265bb67</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/greg_t_7a8f861459a265bb67"/>
    <language>en</language>
    <item>
      <title>What Is a Hash Function? Checksums, Passwords, and Fingerprints</title>
      <dc:creator>GREG T</dc:creator>
      <pubDate>Tue, 22 Sep 2026 05:17:57 +0000</pubDate>
      <link>https://dev.to/greg_t_7a8f861459a265bb67/what-is-a-hash-function-checksums-passwords-and-fingerprints-4chl</link>
      <guid>https://dev.to/greg_t_7a8f861459a265bb67/what-is-a-hash-function-checksums-passwords-and-fingerprints-4chl</guid>
      <description>&lt;p&gt;Hash functions are one of the quiet workhorses of computing. They verify your downloads, identify your git commits, detect duplicate files, and protect stored passwords - all without most people ever noticing. This article explains what a hash function actually does, the differences between the common algorithms, and the single most important thing to understand about them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a hash function does
&lt;/h2&gt;

&lt;p&gt;A hash function takes input of any size - a word, a file, a multi-gigabyte disk image - and produces a fixed-length string called a &lt;strong&gt;hash&lt;/strong&gt; or &lt;strong&gt;digest&lt;/strong&gt;. The same input always produces the same output, but the output looks nothing like the input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hash("hello")  = 5d41402abc4b2a76b9719d911017c592
hash("hellO")  = 8b1a9953c4611296a827abf8c47804d7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how changing a single letter completely transformed the result. This is called the &lt;strong&gt;avalanche effect&lt;/strong&gt;, and it is a defining property of a good hash function: a tiny change in the input produces a wildly different output.&lt;/p&gt;

&lt;h2&gt;
  
  
  The key idea: hashing is one-way
&lt;/h2&gt;

&lt;p&gt;This is the part people most often get wrong. &lt;strong&gt;Hashing is not encryption.&lt;/strong&gt; Encryption is reversible - with the key, you can recover the original. Hashing is deliberately one-way: there is no key, and there is no function that turns a hash back into the original input. The digest is a fingerprint, not a locked box.&lt;/p&gt;

&lt;p&gt;That one-way property is exactly what makes hashing useful for the jobs below. It is also why you must never think of a hash as a way to "hide" data - identical inputs always produce identical hashes, so common values can be looked up in precomputed tables.&lt;/p&gt;

&lt;h2&gt;
  
  
  What hashes are used for
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Verifying downloads.&lt;/strong&gt; A software vendor publishes the SHA-256 of a file. You hash your copy and compare - if the values match exactly, your download is intact and untampered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detecting duplicates.&lt;/strong&gt; Two files with the same hash are (practically certainly) identical, so deduplication systems compare hashes instead of comparing every byte.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storing passwords.&lt;/strong&gt; Servers store the hash of your password, not the password itself. When you log in, they hash what you typed and compare. A breach leaks hashes, not plain passwords - provided the right algorithm was used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data integrity.&lt;/strong&gt; Git identifies every commit by a hash of its contents, which is how it detects corruption and links history together.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  MD5, SHA-1, SHA-256: which to use
&lt;/h2&gt;

&lt;p&gt;Not all hash functions are equal, and some are now broken for security purposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MD5&lt;/strong&gt; - fast but cryptographically broken. Attackers can deliberately create two different inputs with the same MD5 (a "collision"). Never use it for security. It is still fine for non-security tasks like detecting accidental file corruption.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SHA-1&lt;/strong&gt; - also broken for security since 2017. Being phased out everywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SHA-256&lt;/strong&gt; - part of the SHA-2 family and the current general-purpose standard. Fast, widely supported, and with no known practical collisions. This is the right default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SHA-512&lt;/strong&gt; - a larger sibling of SHA-256, useful when you want an even bigger digest.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A crucial note on password hashing
&lt;/h2&gt;

&lt;p&gt;For passwords specifically, even SHA-256 is not enough on its own - it is too fast, which lets attackers try billions of guesses per second. Real password storage uses &lt;strong&gt;deliberately slow&lt;/strong&gt; algorithms designed for the job, such as bcrypt, scrypt, or Argon2, combined with a unique random "salt" per password. If you are building authentication, use one of those, never a plain hash.&lt;/p&gt;

&lt;p&gt;Want to see hashing in action? The generator below computes MD5, SHA-1, SHA-256, and SHA-512 of any text instantly and locally - handy for verifying a checksum or comparing whether two pieces of text are identical.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://devtools.fit/blog/what-is-a-hash-function.html" rel="noopener noreferrer"&gt;devtools.fit&lt;/a&gt;, where I keep a set of free browser-based dev tools.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Understanding Cron Jobs: How to Read and Write Schedules</title>
      <dc:creator>GREG T</dc:creator>
      <pubDate>Sat, 19 Sep 2026 05:12:25 +0000</pubDate>
      <link>https://dev.to/greg_t_7a8f861459a265bb67/understanding-cron-jobs-how-to-read-and-write-schedules-4alg</link>
      <guid>https://dev.to/greg_t_7a8f861459a265bb67/understanding-cron-jobs-how-to-read-and-write-schedules-4alg</guid>
      <description>&lt;p&gt;Behind almost every recurring automated task - nightly backups, hourly data syncs, the weekly report that lands in your inbox every Monday - there is usually a cron job. Cron is the time-based scheduler that has run the Unix world since the 1970s, and its compact syntax now appears far beyond Unix: in GitHub Actions, Kubernetes, cloud functions, and CI pipelines. Learning to read it is a genuinely useful skill.&lt;/p&gt;

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

&lt;p&gt;A standard cron expression is five fields separated by spaces. Each field controls one unit of time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;*  *  *  *  *
|  |  |  |  |
|  |  |  |  +-- &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;week&lt;/span&gt;  (&lt;span class="m"&gt;0&lt;/span&gt;-&lt;span class="m"&gt;7&lt;/span&gt;, &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt; = &lt;span class="n"&gt;Sunday&lt;/span&gt;)
|  |  |  +----- &lt;span class="n"&gt;month&lt;/span&gt;        (&lt;span class="m"&gt;1&lt;/span&gt;-&lt;span class="m"&gt;12&lt;/span&gt;)
|  |  +-------- &lt;span class="n"&gt;day&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt; (&lt;span class="m"&gt;1&lt;/span&gt;-&lt;span class="m"&gt;31&lt;/span&gt;)
|  +----------- &lt;span class="n"&gt;hour&lt;/span&gt;         (&lt;span class="m"&gt;0&lt;/span&gt;-&lt;span class="m"&gt;23&lt;/span&gt;)
+-------------- &lt;span class="n"&gt;minute&lt;/span&gt;       (&lt;span class="m"&gt;0&lt;/span&gt;-&lt;span class="m"&gt;59&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An asterisk (&lt;code&gt;*&lt;/code&gt;) means "every value." So &lt;code&gt;* * * * *&lt;/code&gt; means "every minute of every hour of every day" - the most frequent schedule cron allows.&lt;/p&gt;

&lt;h2&gt;
  
  
  The special characters
&lt;/h2&gt;

&lt;p&gt;Each field accepts more than just a number or an asterisk:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Comma&lt;/strong&gt; for lists: &lt;code&gt;0,15,30,45&lt;/code&gt; in the minute field means at 0, 15, 30, and 45 minutes past the hour.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hyphen&lt;/strong&gt; for ranges: &lt;code&gt;1-5&lt;/code&gt; in the day-of-week field means Monday through Friday.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slash&lt;/strong&gt; for steps: &lt;code&gt;*/15&lt;/code&gt; in the minute field means every 15 minutes; &lt;code&gt;*/2&lt;/code&gt; in the hour field means every other hour.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reading real examples
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt; * * &lt;span class="m"&gt;1&lt;/span&gt;-&lt;span class="m"&gt;5&lt;/span&gt;     -&amp;gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="m"&gt;09&lt;/span&gt;:&lt;span class="m"&gt;00&lt;/span&gt;, &lt;span class="n"&gt;Monday&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;Friday&lt;/span&gt;
*/&lt;span class="m"&gt;15&lt;/span&gt; * * * *    -&amp;gt; &lt;span class="n"&gt;every&lt;/span&gt; &lt;span class="m"&gt;15&lt;/span&gt; &lt;span class="n"&gt;minutes&lt;/span&gt;
&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; * *       -&amp;gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;midnight&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;every&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt;
&lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; * * &lt;span class="m"&gt;0&lt;/span&gt;      -&amp;gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="m"&gt;03&lt;/span&gt;:&lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="n"&gt;every&lt;/span&gt; &lt;span class="n"&gt;Sunday&lt;/span&gt;
&lt;span class="m"&gt;0&lt;/span&gt; */&lt;span class="m"&gt;6&lt;/span&gt; * * *     -&amp;gt; &lt;span class="n"&gt;every&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt; &lt;span class="n"&gt;hours&lt;/span&gt; (&lt;span class="m"&gt;00&lt;/span&gt;:&lt;span class="m"&gt;00&lt;/span&gt;, &lt;span class="m"&gt;06&lt;/span&gt;:&lt;span class="m"&gt;00&lt;/span&gt;, &lt;span class="m"&gt;12&lt;/span&gt;:&lt;span class="m"&gt;00&lt;/span&gt;, &lt;span class="m"&gt;18&lt;/span&gt;:&lt;span class="m"&gt;00&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pattern to internalize: read the fields left to right as minute, hour, day-of-month, month, day-of-week, and translate each special character. With a little practice, &lt;code&gt;0 9 * * 1-5&lt;/code&gt; reads instantly as "9 AM on weekdays."&lt;/p&gt;

&lt;h2&gt;
  
  
  The timezone gotcha that causes outages
&lt;/h2&gt;

&lt;p&gt;Here is the mistake that has broken countless production systems: &lt;strong&gt;classic cron has no timezone field.&lt;/strong&gt; A job runs in whatever timezone the host machine is set to. Most servers run in UTC, so a job you scheduled for "9 AM" fires at 9 AM UTC - which might be 10 or 11 AM where you live, and shifts by an hour when daylight saving time changes.&lt;/p&gt;

&lt;p&gt;If a scheduled report arrives an hour "late" twice a year, this is almost always why. When precise local timing matters, either set the schedule in UTC deliberately, or use a scheduler that supports an explicit timezone.&lt;/p&gt;

&lt;h2&gt;
  
  
  The day-of-month and day-of-week trap
&lt;/h2&gt;

&lt;p&gt;One more surprise: when you set &lt;em&gt;both&lt;/em&gt; the day-of-month and the day-of-week fields, standard cron combines them with OR, not AND. So &lt;code&gt;0 0 13 * 5&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; mean "midnight on Friday the 13th" - it means "midnight on the 13th of every month, &lt;em&gt;and&lt;/em&gt; midnight every Friday." If you only want one of the two conditions, leave the other as &lt;code&gt;*&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test before you deploy
&lt;/h2&gt;

&lt;p&gt;Because a single wrong character can mean a backup that silently never runs, always verify a cron expression before trusting it. The parser below translates any expression into plain English and shows the next several run times, so you can confirm a schedule does exactly what you intended.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://devtools.fit/blog/understanding-cron-jobs.html" rel="noopener noreferrer"&gt;devtools.fit&lt;/a&gt;, where I keep a set of free browser-based dev tools.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Hexadecimal Explained: Why Programmers Count in Base 16</title>
      <dc:creator>GREG T</dc:creator>
      <pubDate>Tue, 15 Sep 2026 13:45:18 +0000</pubDate>
      <link>https://dev.to/greg_t_7a8f861459a265bb67/hexadecimal-explained-why-programmers-count-in-base-16-5an2</link>
      <guid>https://dev.to/greg_t_7a8f861459a265bb67/hexadecimal-explained-why-programmers-count-in-base-16-5an2</guid>
      <description>&lt;p&gt;Color codes like &lt;code&gt;#FF6B35&lt;/code&gt;, memory addresses like &lt;code&gt;0x7FFE&lt;/code&gt;, hashes, MAC addresses, error codes - all of them are written in hexadecimal. For newcomers, base 16 looks intimidating, but it is one of the most useful and approachable ideas in computing once it clicks. Here is the whole concept, from the ground up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Counting beyond ten
&lt;/h2&gt;

&lt;p&gt;We count in &lt;strong&gt;base 10&lt;/strong&gt; because we have ten fingers: the digits 0-9, and when we run out we add a new place (9 -&amp;gt; 10). &lt;strong&gt;Hexadecimal is base 16&lt;/strong&gt;: it has sixteen digits. Since we only have ten number symbols, hex borrows the first six letters of the alphabet for the rest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Decimal:  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Hex:      0 1 2 3 4 5 6 7 8 9  A  B  C  D  E  F
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So &lt;code&gt;A&lt;/code&gt; is ten, &lt;code&gt;F&lt;/code&gt; is fifteen, and the next number after &lt;code&gt;F&lt;/code&gt; is &lt;code&gt;10&lt;/code&gt; in hex - which equals sixteen in decimal. To avoid confusion, hex values are usually prefixed with &lt;code&gt;0x&lt;/code&gt; (as in &lt;code&gt;0x10&lt;/code&gt;) or &lt;code&gt;#&lt;/code&gt; for colors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Converting hex to decimal
&lt;/h2&gt;

&lt;p&gt;Each position in a hex number is a power of 16, read right to left: the rightmost digit is the 1s place, then 16s, then 256s, and so on. Take &lt;code&gt;0x2F&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2F = (2 x 16) + (15 x 1)
   = 32 + 15
   = 47
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;code&gt;0xFF&lt;/code&gt;, the famous maximum of a single byte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FF = (15 x 16) + (15 x 1) = 240 + 15 = 255
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why hex and binary are best friends
&lt;/h2&gt;

&lt;p&gt;Here is the reason hex dominates programming: &lt;strong&gt;one hex digit represents exactly four binary digits (bits).&lt;/strong&gt; Four bits can hold sixteen values - precisely the range of one hex digit. That makes the conversion mechanical:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Binary:  1111 1111
Hex:        F    F   =  0xFF
Binary:  0010 1010
Hex:        2    A   =  0x2A
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A byte is eight bits, so it is always exactly two hex digits. This is why memory dumps, color channels, and hashes are shown in hex: it is a compact, lossless shorthand for binary that humans can actually read. Writing &lt;code&gt;0xFF&lt;/code&gt; is far easier than &lt;code&gt;11111111&lt;/code&gt;, and you can convert between them in your head once you memorize the sixteen patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where you will meet hexadecimal
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Colors:&lt;/strong&gt; &lt;code&gt;#FF6B35&lt;/code&gt; is three bytes - red &lt;code&gt;FF&lt;/code&gt; (255), green &lt;code&gt;6B&lt;/code&gt; (107), blue &lt;code&gt;35&lt;/code&gt; (53).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory addresses:&lt;/strong&gt; debuggers and low-level code show locations like &lt;code&gt;0x7FFE3210&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hashes and checksums:&lt;/strong&gt; an MD5 or SHA value is just a long hex string.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Character codes:&lt;/strong&gt; Unicode code points are written as &lt;code&gt;U+1F600&lt;/code&gt; in hex.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions and flags:&lt;/strong&gt; bit masks are often expressed in hex for compactness.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Octal, the third base
&lt;/h2&gt;

&lt;p&gt;You will occasionally see &lt;strong&gt;base 8 (octal)&lt;/strong&gt;, most famously in Unix file permissions: &lt;code&gt;chmod 755&lt;/code&gt;. Each octal digit encodes three permission bits for owner, group, and others. Octal groups bits in threes the way hex groups them in fours.&lt;/p&gt;

&lt;p&gt;The fastest way to build intuition is to convert numbers back and forth and watch the patterns. The converter below shows binary, octal, decimal, and hex side by side - type in any field and the others update instantly.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://devtools.fit/blog/hexadecimal-explained.html" rel="noopener noreferrer"&gt;devtools.fit&lt;/a&gt;, where I keep a set of free browser-based dev tools.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>camelCase vs snake_case vs kebab-case: Naming Conventions Explained</title>
      <dc:creator>GREG T</dc:creator>
      <pubDate>Wed, 09 Sep 2026 05:48:28 +0000</pubDate>
      <link>https://dev.to/greg_t_7a8f861459a265bb67/camelcase-vs-snakecase-vs-kebab-case-naming-conventions-explained-63f</link>
      <guid>https://dev.to/greg_t_7a8f861459a265bb67/camelcase-vs-snakecase-vs-kebab-case-naming-conventions-explained-63f</guid>
      <description>&lt;p&gt;Every programmer eventually wonders: should this variable be &lt;code&gt;userName&lt;/code&gt;, &lt;code&gt;user_name&lt;/code&gt;, or &lt;code&gt;user-name&lt;/code&gt;? These are not random style choices - each convention has a name, a history, and a set of languages and contexts where it is the norm. Getting them right makes your code look native to the ecosystem you are working in. Here is the complete map.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four main conventions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;camelCase&lt;/strong&gt; - first word lowercase, each following word capitalized: &lt;code&gt;userName&lt;/code&gt;, &lt;code&gt;maxRetryCount&lt;/code&gt;. Named because the capital letters look like a camel's humps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PascalCase&lt;/strong&gt; (also called UpperCamelCase) - like camelCase but the first letter is also capitalized: &lt;code&gt;UserName&lt;/code&gt;, &lt;code&gt;HttpClient&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;snake_case&lt;/strong&gt; - all lowercase, words joined by underscores: &lt;code&gt;user_name&lt;/code&gt;, &lt;code&gt;max_retry_count&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;kebab-case&lt;/strong&gt; (also called dash-case) - all lowercase, words joined by hyphens: &lt;code&gt;user-name&lt;/code&gt;, &lt;code&gt;main-content&lt;/code&gt;. Named because the words look skewered like a kebab.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also &lt;strong&gt;SCREAMING_SNAKE_CASE&lt;/strong&gt; - snake_case in all capitals (&lt;code&gt;MAX_SIZE&lt;/code&gt;, &lt;code&gt;API_KEY&lt;/code&gt;) - reserved almost everywhere for constants.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which convention goes where
&lt;/h2&gt;

&lt;p&gt;The conventions are not interchangeable; communities have settled on strong norms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript / TypeScript:&lt;/strong&gt; camelCase for variables and functions, PascalCase for classes and React components.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python:&lt;/strong&gt; snake_case for variables and functions, PascalCase for classes, SCREAMING_SNAKE_CASE for constants (this is the PEP 8 standard).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ruby:&lt;/strong&gt; snake_case for methods and variables, PascalCase for classes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go:&lt;/strong&gt; PascalCase for exported names, camelCase for unexported ones - capitalization is actually meaningful to the compiler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS:&lt;/strong&gt; kebab-case for class names and custom properties (&lt;code&gt;--main-color&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URLs and file names:&lt;/strong&gt; kebab-case, because hyphens are read as word separators by search engines and are easy to read in links.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database columns:&lt;/strong&gt; usually snake_case.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why hyphens cannot be used in code
&lt;/h2&gt;

&lt;p&gt;You may wonder why kebab-case is fine for CSS and URLs but never for variables. The reason is that most programming languages interpret the hyphen as the minus operator - &lt;code&gt;user-name&lt;/code&gt; would be parsed as "user minus name." That is why code uses camelCase or snake_case (both made only of letters, digits, and underscores) while markup and URLs, which have no arithmetic, can use hyphens freely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Converting between conventions
&lt;/h2&gt;

&lt;p&gt;Renaming identifiers from one convention to another by hand is tedious and error-prone, especially across a large file or when porting code between languages. The mechanical rules are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;To camelCase / PascalCase:&lt;/strong&gt; remove separators, capitalize the letter after each removed separator.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;To snake_case / kebab-case:&lt;/strong&gt; insert a separator before each capital letter, then lowercase everything.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Edge cases - acronyms like &lt;code&gt;HTTPServer&lt;/code&gt;, leading capitals, numbers - are where manual conversion tends to slip. A converter handles them consistently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consistency beats correctness
&lt;/h2&gt;

&lt;p&gt;If there is one rule above all others, it is this: &lt;strong&gt;match the surrounding code.&lt;/strong&gt; A "wrong" convention used consistently is far more readable than the "right" one applied haphazardly. When you join a project, adopt its conventions even if they differ from your personal preference. Linters and formatters can enforce this automatically.&lt;/p&gt;

&lt;p&gt;Need to switch some text between cases right now? Paste it into the converter below and get UPPERCASE, lowercase, Title Case, camelCase, PascalCase, snake_case, and kebab-case in one click.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://devtools.fit/blog/camelcase-vs-snake-case.html" rel="noopener noreferrer"&gt;devtools.fit&lt;/a&gt;, where I keep a set of free browser-based dev tools.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>codenewbie</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What Is a JWT? JSON Web Tokens Explained Simply</title>
      <dc:creator>GREG T</dc:creator>
      <pubDate>Sat, 05 Sep 2026 05:28:41 +0000</pubDate>
      <link>https://dev.to/greg_t_7a8f861459a265bb67/what-is-a-jwt-json-web-tokens-explained-simply-4bo3</link>
      <guid>https://dev.to/greg_t_7a8f861459a265bb67/what-is-a-jwt-json-web-tokens-explained-simply-4bo3</guid>
      <description>&lt;p&gt;JSON Web Tokens - JWTs, usually pronounced "jots" - are the most common way modern web applications prove who you are after you log in. If you have ever inspected the network traffic of a web app and seen a long string in three dot-separated parts, that was almost certainly a JWT. Here is what they are and how they work, without the jargon.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem JWTs solve
&lt;/h2&gt;

&lt;p&gt;HTTP is stateless: each request arrives with no memory of the previous one. So after you log in, how does the server know it is still you on the next request? The traditional answer was &lt;strong&gt;server-side sessions&lt;/strong&gt;: the server stores your session in memory or a database and gives you a cookie with a session ID. That works, but it means the server has to look up and store state for every logged-in user.&lt;/p&gt;

&lt;p&gt;JWTs flip this around. Instead of the server remembering you, it gives you a signed token that &lt;em&gt;contains&lt;/em&gt; your identity. On each request you send the token back, and the server simply verifies the signature. No lookup, no shared session store - which is why JWTs scale so well across multiple servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three parts of a JWT
&lt;/h2&gt;

&lt;p&gt;A JWT is three Base64Url-encoded pieces joined by dots: &lt;code&gt;header.payload.signature&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiQWxpY2UifQ.SflKxw...
        header                    payload                signature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Header&lt;/strong&gt; - says what type of token it is and which signing algorithm was used (for example &lt;code&gt;HS256&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payload&lt;/strong&gt; - the "claims": the actual data, such as the user ID (&lt;code&gt;sub&lt;/code&gt;), name, roles, and an expiry time (&lt;code&gt;exp&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Signature&lt;/strong&gt; - a cryptographic seal over the header and payload, created with a secret key only the server knows.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The most important thing to understand
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A JWT is signed, not encrypted.&lt;/strong&gt; The payload is merely Base64-encoded, which is trivially reversible - anyone who has the token can read its contents. Paste any JWT into a decoder and the claims appear in plain text, no key required.&lt;/p&gt;

&lt;p&gt;So what does the signature protect? &lt;strong&gt;Tampering.&lt;/strong&gt; If an attacker changes the payload - say, flipping &lt;code&gt;"role": "user"&lt;/code&gt; to &lt;code&gt;"role": "admin"&lt;/code&gt; - the signature no longer matches, and the server rejects the token. The signature proves the token was issued by your server and has not been altered; it does &lt;em&gt;not&lt;/em&gt; hide the contents.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you should and should not put in a JWT
&lt;/h2&gt;

&lt;p&gt;Because the payload is readable by anyone holding the token, treat it as public:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Good to include:&lt;/strong&gt; a user ID, roles or permissions, the token's expiry. Just enough to identify the session.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never include:&lt;/strong&gt; passwords, credit card numbers, personal data, or any secret. If the token leaks into a log, a URL, or browser history, everything in it is exposed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Expiry and security tips
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Always set an expiry (&lt;code&gt;exp&lt;/code&gt;).&lt;/strong&gt; A token that never expires is a permanent key if stolen. Short lifetimes (minutes to hours) limit the damage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use refresh tokens&lt;/strong&gt; for long sessions: a short-lived access token plus a longer-lived refresh token that can be revoked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store them carefully&lt;/strong&gt; in the browser. &lt;code&gt;localStorage&lt;/code&gt; is vulnerable to cross-site scripting; &lt;code&gt;HttpOnly&lt;/code&gt; cookies are safer against that particular attack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Most "login bugs" are expiry bugs.&lt;/strong&gt; When debugging a 401, decode the token and check the &lt;code&gt;exp&lt;/code&gt; claim first - it is usually expired or the server clock is off.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To see what is inside a token, paste it into the decoder below. It splits the JWT and shows the header and payload - including human-readable dates for the issued-at and expiry claims - entirely in your browser, so the token is never sent anywhere.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://devtools.fit/blog/what-is-a-jwt.html" rel="noopener noreferrer"&gt;devtools.fit&lt;/a&gt;, where I keep a set of free browser-based dev tools.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
