Extracting GUIDs from a bunch of text

As part of messing with Windows Performance Recorder profiles, I had a need to extract everything that looks like a GUID from a blob of text.

So I wrote this script. It digs through its STDIN and outputs all the GUID-looking things, uppercase-ized and sorted.


Perl scripts to encrypt and decrypt text using Rijndael

I talked about Rijndael in a few previous posts: Expressing a function f: GF(2⁸) → GF(2⁸) as a polynomial using a Lagrange polynomial, Generating the Rijndael S-box, Efficient multiplication and division in GF(28), Sieving irreducible monic polynomials over a finite field, Addition and multiplication table for GF(22).

Today I wrote a couple of Perl scripts which use off-the-shelf CPAN modules to encrypt and decrypt text using a passphrase. For ease of transport, at the cost of some storage space, the encrypted payload is Base64 encoded.

The particular CPAN modules in question are Crypt::CBC and Crypt::Rijndael.

encrypt.pl and decrypt.pl source in my GitHub repository. They operate on STDIN and produce output on STDOUT.

Note that if you pass an incorrect passphrase to decrypt.pl you get garbage output, rather than an error.

Here is a secret message which is encoded with the passphrase “hunter2”: encrypted.txt (right-click the link and save, rather than opening it in the browser.)

Perl script to parse MPEG audio header

I’ve written a Perl script which will parse MPEG audio headers and display them in a human-readable format.

For example, if you run it on ding.mpeg (download from GitHub) you get this output:

>perl mpegaudioheader.pl ding.mpeg
Frame header: 11111111 111 (should be all ones)
MPEG Audio version ID: 11 (MPEG version 1 (ISO/IEC 11172-3))
Layer description: 10 (layer II)
Protection bit: 0 (protected by CRC (16-bit CRC follows header))
Bitrate index: 1011 (224 kbps)
Sample rate index: 00 (44100 Hz)
Padding bit: 0 (frame is not padded)
Private bit: 0 (application specific)
Channel mode: 00 (stereo)
Mode extension (if channel mode is joint stereo:) 00 (bands 4 to 31)
Copyright: 0 (audio is not copyrighted)
Original: 0 (copy of original media)
Emphasis: 00 (none)

Here’s the source for the Perl script on GitHub

Note this script assumes that the very first bytes of the file are the MPEG audio header, and makes no effort to dig into the file to find the audio header.

EDIT 2015-10-31: moved script to https://github.com/mvaneerde/blog/blob/master/scripts/mpegaudioheader.pl

Bad Perl: locker problem

Bad Perl solution to the “print the open lockers” problem:

perl -e"print join', ',map{$_*$_}1..sqrt pop" 100

54 characters.  I prefer this to the 53-character solution obtained by omitting the space after the first comma.

EDIT: 49 characters:

perl -e"print map{$_*$_,' '}1..sqrt pop" 100

EDIT: 48:

perl -e"print map{$_*$_.$/}1..sqrt pop" 100

EDIT: 47:

perl -e"map{print$/.$_*$_}1..sqrt pop" 100

I still think “say” is cheating but it does afford this very short solution:

perl -E"map{say$_*$_}1..sqrt pop" 100

EDIT: Apparently I need to learn how to count. Counts above are off. Anyway, 41:

perl -e"print$_*$_,$/for 1..sqrt pop" 100

Bad Perl: Josephus problem

Another programming contest asks to solve the Josephus problem.

Bad Perl solution (83 characters… so close…)

>perl -e"@_=(1..$ARGV[0]);++$c%$ARGV[1]?$i++:splice@_,$i%=@_,1while$#_;print@_" 40 3

EDIT: got it down to 80.

>perl -e"@_=(1..shift);++$c%$ARGV[0]?$i++:splice@_,$i%=@_,1while$#_;print@_" 40 3

EDIT2: 78 dropping the parentheses.

>perl -e"@_=1..shift;++$c%$ARGV[0]?$i++:splice@_,$i%=@_,1while$#_;print@_" 40 3

EDIT3: 66, shamelessly cannibalizing others’ ideas from the contest (though I refuse to use “say”)

>perl -e"$k=pop;@_=1..pop;@_=grep{++$i%$k}@_ while$#_;print@_" 40 3

Bad Perl: Russian Peasant multiplication algorithm

I found this programming contest interesting: here’s what I’ve got.

perl -e "($a,$b)=@ARGV;map{$c+=$_*$b}grep{$a&$_}map{1<<$_}(0..log($a)/log 2);print$c" 7 19

I’m calling this a one-liner because the part between the quotes is less than 80 characters (75, to be exact.)  The full command line goes over 😦

Requires the inputs to be positive whole numbers.

Perfect example of Bad Perl.  Exercise: rewrite in Good Perl.

EDIT: got the whole thing down to 80 characters (with single-digit multiplicands.)

perl -e "($a,$b)=@ARGV;map{$c+=$b<<$_ if$a>>$_&1}(0..log($a)/log 2);print$c" 8 7

Good Perl, Bad Perl

One of my favorite languages is Perl.  Perl has an ambivalent reputation; some people take to it, some accuse it of being a syntax-complete language.  (There’s some truth to this.)

My view is that Perl gives you a very direct link into the mind of the programmer – much more so than other languages.  Perl is designed very much like a spoken language, perhaps because Larry Wall‘s background is linguistics.

There was a little girl
Who had a little curl
Right in the middle of her forehead.
And when she was good,
She was very, very, good;
But when she was bad
She was horrid.
— Henry Wadsworth Longfellow

(In an English accent, “forehead” and “horrid” actually rhyme.)

Two examples of my own Perl to illustrate my point.  This is in my email signature:

perl -e "print join er,reverse',','l hack',' P','Just anoth'"

And this little seasonal gem:

twelve-days-of-christmas.pl in GitHub

The latter kind of Perl I like to call “good Perl”.  It’s easy to read, I think.  There are a couple of idioms that take getting used to, just like with any new language, but well-written Perl is (I think) easier to read than any other language.

But flexibility has its dark sides as well.  Black Perl is the canonical example, but there are others such as Perl golf.  This kind of thing (the first sample above is an example) is responsible for at least part of Perl’s reputation for opacity; its compatibility with shell scripting, and most particularly its embedded regular expression support, is responsible for much of the rest.

Exercise: duplicate the output of the second sample above using as short a Perl program as possible.

EDIT 2020-10-22: moved Good Perl example into GitHub