Friday, August 14, 2009

Combo locks

I had a few old Master combination locks lying around and decided to retrieve the combinations as described here. Being a geek, I wrote a script to help me keep track. Using this I was able to get all combos at less than 10 minutes per lock. Of course, it took me a good 20-30 minutes to write the script, but that was more fun than spinning a combination lock.
Also, this is far from an advanced shell script, but the nice thing about it is that it's quick, dirty, and easy. You can actually do a lot with bash very quickly once you get to know it, and one nice thing about bash vs. Perl is that it's really easy to get a gut feeling when bash isn't going to cut it and Perl is the way to go, for example when you need to parse a huge amount of data or do some really complicated regex work.
Anyway, if this helps you, then great, if not then at least it's documented somewhere...

[Edit: sorry if feed readers got this multiple times, I had to fix a couple of typos...]

##########START#############
#!/bin/bash

# Bash script to print out all likely combos for a master combo lock. Rough and ready but it works
# Written by Nate Aiman-Smith (http://staunchtech.blogspot.com). To be run as-is by a non-priviliged user.

## Variables
# One argument - the last number.
# See http://www.fusor.us/lockpick.html for a simple explanation on how to get it
thirdnum=$1

# File to keep track of tried combos. Replace with your preferred place if required
trackfile="/tmp/triednums_$thirdnum"

# Difference between first and second numbers that we'll print out - more than 24 is, in my very limited experience, unlikely.
# With more practice could probably get a better number.
fastdistance=24

## Functions

verify_nums() {
num=$mod
while [ $num -lt 40 ]
do
if [ $num=$thirdnum ]
then return 0
fi
num=`expr $num '+' 4`
done
return 1
}

print_valid_firstnums() {
num=$mod
while [ $num -lt 40 ]
do
echo -n "$num "
num=`expr $num '+' 4`
done
echo
}

print_combos() {
mod=`expr $firstnum '%' 4`
mod=`expr $mod '+' 2`
mod=`expr $mod '%' 4`
num=$mod
while [ $num -lt 40 ]
do
# Swap the two lines if you want to get the _unlikely_ combos...
if check_distance
#if ! check_distance
then echo "$firstnum $num $thirdnum"
fi
num=`expr $num '+' 4`
done
}

# To facilitate, let's try to stick to second numbers that are
# less than $fastdistance away from the first
check_distance() {
secondnum=$num
# Equal numbers always fail
if [ $secondnum -eq $firstnum ]
then return 1
elif [ $secondnum -lt $firstnum ]
then
secondnum=`expr $secondnum '+' 40`
fi
diff=`expr $secondnum '-' $firstnum`
if [ $diff -gt $fastdistance ]
then
return 1
fi
return 0
}

##Main

if [ ! $thirdnum -lt 40 ]
then
echo "invalid number"
exit 1
fi

if [ -f $trackfile ]
then
echo "Found tracking file $trackfile - hit ctrl-C, delete the file, and start over if you want to start fresh"
fi

mod=`expr $thirdnum '%' 4`
for valid in `print_valid_firstnums`
do
if ! grep "^$valid" $trackfile &> /dev/null
then
echo "Combinations for $valid:"
firstnum=$valid
print_combos
echo "Press return when done, hit ctrl-C if you bail"
read blankline
echo $valid >> $trackfile
fi
done
############END################

No comments: