Luhn Validation From the Command Line

Published: June 12, 2018


Today I received an alert that a credit card scanning tool had detected data that looked like a credit card number (PAN) on the file system of a client’s server.

Reviewing the details I found that the tool was reporting it had found what appeared to be a credit card number in an image file on the server. This gave me quite the scare as I knew that there’s a common strain of malware for Magento (the platform this site was running) which steals credit card numbers and stores them in images files to be harvested by the attacker.

The tool was reporting the credit card number started with “304428”. I was able to find the match in the reported file using exiftool

$ exiftool -m 00080878182947_2.jpg | grep -o '.\{20\}304428.\{20\}'
8cca4b4231, xmp.did:304428740720681188C6DBD8EA

xmp.did:? I wasn’t sure what this was, but from some quick research I learned that it was metadata added for Adobe’s Extensible Metadata Platform (“XMP”).

As a quick check I did want to see if the number passed Luhn validation. I didn’t want to copy / paste the data into an online tool for obvious reasons, so I decided to do some further research on how to run Luhn validation from the command line. Here I’ll document my findings.

No Built Ins!

As far as I can tell, there are no built in commands on Unix systems to do this. Additionally, I checked how to do this in many common languages (Python, Ruby, PHP) and didn’t see native functions for this in any of them. Time to look for alternatives.

Using node

My system had node and npm installed, so I decided to look for an npm package to do this, knowing that there are npm packages for just about everything under the sun. Shortly thereafter I arrived at the landing page for the luhn package on I decided to install it…

$ npm install -g luhn

Next I started the node console and tested things out…

$ node
> var luhn = require("luhn");
> luhn.validate("3044287407206811")

Success :raised_hands: (Interestingly, though, the tool flagged this data as a credit card number, even though it didn’t pass Luhn validation :thinking:)

If You Don’t Want to Use Node

If you don’t have node and npm installed and don’t want to go the node route there’s a pure bash implementation here. You can add this function to your ~/.bashrc (or ~/.zshrc or whatever you use) and call it as follows…

$ isLUHNValid 3044287407206811

If it passes it will exit with exit code 0. Otherwise it will exit with exit code 1.

$ isLUHNValid 3044287407206811
$ echo $?
$ isLUHNValid 4111111111111111
$ echo $?

Max Chadwick Hi, I'm Max!

I'm a software developer who mainly works in PHP, but loves dabbling in other languages like Go and Ruby. Technical topics that interest me are monitoring, security and performance. I'm also a stickler for good documentation and clear technical writing.

During the day I lead a team of developers and solve challenging technical problems at Something Digital where I mainly work with the Magento platform. I've also spoken at a number of events.

In my spare time I blog about tech, work on open source and participate in bug bounty programs.

If you'd like to get in contact, you can find me on Twitter and LinkedIn.