Photo-1 Photo-2 Photo-3 Photo-4 Photo-5 Photo-6

@brentmc79

@brentmc79

Full-time web developer. Part-time smart ass.

I'm Brent Collier.

After a year and a half as an engineer on Twitter's Trust & Safety team, I'm looking for my next gig. Contact me if you know of something interesting.

#

IP Address Regular Expressions

Posted on 09/26/2014

A regular expression for any ole ip address is pretty simple

\d{1,3}(?:\.\d{1,3}){3}

It basically just looks for 1-3 digits and (period, 1-3 digits) x 3. So that'll match 0.0.0.0 or 255.255.255.255 or whatever. The problem though, is it will also match 999.999.999.999 and last time I checked, that's not a valid ip address.

For single digits, number ranges are super simple in regular expressions...

  • \d is 0..9
  • [0-9] is also 0..9
  • [2-7] is 2, 3, 4, 5, 6, or 7

It's when you get into multi-digit number ranges that things get hairy. For our ip address regex, no digit group should exceed 255. Heres the regex to match 0..255

(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|\d)

And here it is within the ip address regex

(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|\d)){3}

That will match 0.0.0.0 up to 255.255.255.255, but not 255.255.255.256. What about zero-padded ip addresses? Well, first here's 000..255

(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)

And if we expand that into a fill ip address expression

(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)){3}

Depending on how you need to use the regular expression, it may be helpful to bound it to the beginning/end of the string

^(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)){3}$

You can see it in action here.

Here's a few others to match typical private ip ranges

10.0.0.0 - 10.255.255.255

^10(?:\.(?:00\d|\d|0\d\d|\d\d|1\d\d|2[0-4]\d|25[0-5])){3}$

172.16.0.0 - 172.31.255.255

^172\.(?:\d|[1-2]\d|3[01])(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)){2}$

192.168.0.0 - 192.168.255.255

^192\.168(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)){2}$
#

UndefinedConversionError can suck it

Posted on 09/04/2014

I have a bit of code in our app that downloads binary files and writes them to Tempfiles. Some testing led to the following exception:

An Encoding::UndefinedConversionError occurred in analyses#create:

  "\x90" from ASCII-8BIT to UTF-8
  app/models/analysis/malware.rb:193:in `get_file'

Line 193 looked basically like this:

tempfile = Tempfile.new('tmp')
begin
  tempfile.write(uploader.file.read)
ensure
  tempfile.close
end

I actually didn't want it converted to UTF-8, so a quick perusal of the Tempfile docs told me that I just needed to specify the encoding when I initialized the Tempfile.

So I changed the first line to:

tempfile = Tempfile.new('tmp', :encoding => 'ascii-8bit')

And everything was kosher.

#

Formatting JSON in Vim

Posted on 01/21/2014

Typically when I'm dealing with JSON data, it's in the browser and I can use the handy JsonView Chrome extension, but in this particular instance it was a text file containing a string of json.

A quick google search led me to this blog post.

To format a file as json, run this command in Vim:

:%!python -m json.tool

Or, add this to your .vimrc, then select the bit of json and hit <mapleader>j.

map <Leader>j !python -m json.tool<CR>

Awesome.