Comparison of markup languages
I've been investigating JSON vs YAML vs TOML for various applications. After testing many variations I ended up writing a simple tool to compare all three live.
Tags:I've been investigating JSON vs YAML vs TOML for various applications. After testing many variations I ended up writing a simple tool to compare all three live.
Tags:To display a message when a user logs into your server, add the following to ~/.bashrc:
# If it's an interactive terminal show the banner
if [[ $- == *i* ]]; then
echo "Welcome to the monitoring server"
echo "Configuration is stored in /etc/myapp"
fi
This runs only for interactive sessions. Non-interactive connections such as SFTP and SCP remain unaffected, which prevents automated processes from breaking.
Tags:The more I learn about YAML, the more I like it. JSON is great as a machine readable format, but it sucks at being human readable. Want to add an element, better make sure you have all the commas and curly braces in the exact right place or the whole thing will be unusable. YAML on the other hand is designed to be human readable and modifiable. It's a very simple key/value system using indentation to represent layers.
PHP has a PECL module with good YAML support. There are also pure PHP versions if you're unable to install PECL modules. Symfony provides one, and so does Spyc. I prefer the latter because it's a single file and very easy to install.
On the Perl side there is YAML::XS, YAML::PP, and many others.
Parsing YAML is very easy in just about every language I can find. If you have a complex data structure that you need humans to interact with use YAML please.
Here is a great breakdown of when to use YAML vs JSON:
| Use Case | Recommended | Why |
|---|---|---|
| API request/response | JSON | Universal support, strict parsing |
| Configuration files | YAML | Comments, readability |
| Browser/JavaScript | JSON | Native parsing |
| Kubernetes/Docker | YAML | Industry standard |
| Data interchange | JSON | Unambiguous, fast |
| Human-edited files | YAML | Less punctuation |
Often I need to generate random unsigned integers for seeding PRNGs. The best way is using the getentropy() system function to read OS level randomness into your array.
#include <sys/random.h>
// Read from system random to fill up data structure
int8_t fill_urandom(void *buf, size_t bytes) {
int8_t ok = getentropy(buf, bytes);
return (ok == 0);
}
Declare your array of integers, and then pass it as a pointer to this function to fill with random bytes from your OS. This will get you a bunch of random integers you can use for seeding PRNGs.
uint64_t seed[4];
fill_urandom(seed, sizeof(seed));
Tags:
List of books I read in 2026. Also see the list of 2025. The date indicated denotes the date I started reading the book.
2026-01-01 - White Fang by Jack London - 180 pages
2026-01-03 - Hollow Man by John Dickson Carr - 213 pages
2026-01-06 - The Three-body Problem by Cixin Liu - 400 pages
2026-01-12 - Star Wars: Revelation by Karen Traviss - 410 pages
2026-01-19 - Pale Blue Dot by Carl Sagan - 342 pages
2026-01-25 - Dungeon Crawler Carl by Matt Dinniman - 450 pages
2026-02-01 - Project Hail Mary by Andy Weir - 478 pages
2026-02-09 - The Dark Forest by Cixin Liu - 512 pages
2026-02-18 - The Hike by Drew Magary - 278 pages
2026-02-22 - Fletch by Gregory Mcdonald - 249 pages
2026-02-26 - Zen And The Art Of Motorcycle Maintenance by Robert M. Pirsig - 540 pages
2026-03-06 - Aliens: The Female War by Steve Perry - 258 pages
2026-03-11 - The Crystal Cave by Mary Stewart - 522 pages
2026-03-20 - Nexus by Yuval Noah Harari - 420 pages
2026-03-26 - Star Wars: Onslaught by Michael A. Stackpole - 292 pages
2026-03-31 - Death's End by Cixin Liu - 590 pages
2026-04-09 - The Call Of The Wild (puffin Classics) by Jack London - 160 pages
In the extended edition of Fellowship of the Ring Gandalf fights the Balrog and then falls for about 70 seconds.
It takes about 12 seconds to reach terminal velocity: 0.5 * g * t^2 = 0.5 * 9.81 * 12^2 ~ 706m
The remaining 58 seconds Gandalf is at terminal velocity (not speeding up) of 53m/s which is v * t = 53 * 58 ~ 3074m. For a total of 3780 meters, or about 2.35 miles.
Pretty impressive free-fall considering they were ALREADY under ground.
Tags:Biski64 is a new PRNG there is extremely fast and also very simple. This one was pretty simple so I ported it to Perl in biski64.pl.
SFC64 is also largely considered on of the better PRNGs so I ported it also in sfc64.pl.
Tags:I found a PCG64 implementation that I was able to borrow and convert to pure Perl:
# PCG64 RXS-M-XS "simple" variant
#my $seeds = [12, 34];
#my $rand = pcg64_perl($seeds);
sub pcg64_perl {
my $seeds = $_[0];
my $ret = (($seeds->[0] >> (($seeds->[0] >> 59) + 5)) ^ $seeds->[0]);
use integer;
$ret *= 12605985483714917081;
$seeds->[0] = $seeds->[0] * 6364136223846793005 + $seeds->[1];
no integer;
$ret = ($ret >> 43) ^ $ret;
return $ret;
}
Update: Bonus points because it's really fast:
* Rate xosh256** biski64 sfc64 PCG32 Splitmix64 PCG64
xosh256** 1589825/s -- -26% -48% -52% -58% -65%
biski64 2145923/s 35% -- -30% -35% -43% -53%
sfc64 3058104/s 92% 43% -- -8% -19% -33%
PCG32 3311258/s 108% 54% 8% -- -13% -28%
Splitmix64 3787879/s 138% 77% 24% 14% -- -17%
PCG64 4587156/s 189% 114% 50% 39% 21% --
Tags:
I have some large audio files that I need to serve via HTTPs. They need to be protected by my PHP login system so they cannot live inside of the webroot. Fortunately there is a nifty Apache module named X-sendfile, that lets you serve files outside of the webroot.
Credential checking is done in PHP, and then you set a special HTTP header that Apache watches for. When Apaches sees the X-Sendfile header it serves the file directly. This gets you all the advantages of a full-blown HTTP server handling your files, but the convenience and simplicity of PHP for handling authentication.
if ($authorized) {
$mime_type = mime_from_filename($filepath);
header("Content-Type: $mime_type");
header("X-Sendfile: $filepath");
exit;
}
See also: Get mime type for file
Tags:If you need to get the mime type for a file in PHP you can use this function which wrappers the finfo_open() function.
function mime_from_filename($filename) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $filename);
finfo_close($finfo);
return $mine;
}
Note: This function requires the file to exist on the disk.
Tags:If you need a fast and simple way to get the terminal width in Perl core use Term::ReadKey. This is almost certainly faster and better than shelling out to tput cols.
sub get_terminal_width {
my @x = Term::ReadKey::GetTerminalSize();
my $width = $x[0] || 0;
return $width;
}
Tags:
Current NIST Password Requirements for 2025 (SP800-63b).
What’s gone:
❌ Required uppercase, numbers, and symbols
❌ Mandatory password resets every 90 days
❌ Arbitrary complexity policies
What’s required now:
✅ Minimum 8-character passwords (15+ for privileged accounts)
✅ Password screening against compromised credential databases
✅ Support for passwordless authentication and passkeys
Minimum Password Length Requirements
Password length serves as the cornerstone of NIST's updated authentication framework. While the baseline requirement mandates a minimum of 8 characters, security research reveals that passwords under 8 characters can be cracked within hours using modern computing power.
StrongDM has a good summary.
Tags:In my ongoing quest to implement PRNGs in pure Perl I'm adding the Marsaglia multiply-with-carry family to my collection. These were a little difficult because the math is all done in 128bits which requires a special emulation layer in Perl. The Perl version is much slower than the C version, but that's to be expected without native 128bit variable types.
I also implemented squares64 PRNG which was a little more straight forward. I learned that bitwise shifts are normally unsigned, but if we're in a use integer block bitwise shifts change to signed. This is not what we want so I ended doing a lot of use integer followed almost immediately by a no integer to make sure we're doing the math in the correct mode.
For the fourth year in a row I made it into the official Perl release notes. People get mentioned if they contribute code to the language. To be fair my contributions were documentation updates, but it's still pretty cool to get referenced in the official release announcement that goes out to the entire world.
Tags:I need to print all the lines in a text file after a certain time. You can do this pretty easily with a Perl one-liner:
perl -nE 'if (/13:00/) { $found = 1; next } print if $found' /var/log/messages
The delimiter needs to be in the file to trigger. If there was no line that matches 13:00 nothing will print.
Update: This can also be accomplished with awk:
awk '/13:00/ {found=1; next} found' /var/log/messages
Tags: