Skip to content

Instantly share code, notes, and snippets.

@gavinwahl
Created December 7, 2011 23:54
Show Gist options
  • Save gavinwahl/1445362 to your computer and use it in GitHub Desktop.
Save gavinwahl/1445362 to your computer and use it in GitHub Desktop.
commit-msg hook that checks Verheoff checksums
#! /usr/bin/env python
# Verhoeff implementation from Hermann Himmelbauer,
# http://en.wikibooks.org/wiki/Algorithm_Implementation/Checksums/Verhoeff_Algorithm#Python
verhoeff_table_d = (
(0,1,2,3,4,5,6,7,8,9),
(1,2,3,4,0,6,7,8,9,5),
(2,3,4,0,1,7,8,9,5,6),
(3,4,0,1,2,8,9,5,6,7),
(4,0,1,2,3,9,5,6,7,8),
(5,9,8,7,6,0,4,3,2,1),
(6,5,9,8,7,1,0,4,3,2),
(7,6,5,9,8,2,1,0,4,3),
(8,7,6,5,9,3,2,1,0,4),
(9,8,7,6,5,4,3,2,1,0))
verhoeff_table_p = (
(0,1,2,3,4,5,6,7,8,9),
(1,5,7,6,2,8,3,0,9,4),
(5,8,0,3,7,9,6,1,4,2),
(8,9,1,6,0,4,3,5,2,7),
(9,4,5,3,1,2,6,8,7,0),
(4,2,8,6,5,7,3,9,0,1),
(2,7,9,3,8,0,6,4,1,5),
(7,0,4,6,9,1,3,2,5,8))
verhoeff_table_inv = (0,4,3,2,1,5,6,7,8,9)
def calcsum(number):
"""For a given number returns a Verhoeff checksum digit"""
c = 0
for i, item in enumerate(reversed(str(number))):
c = verhoeff_table_d[c][verhoeff_table_p[(i+1)%8][int(item)]]
return verhoeff_table_inv[c]
def checksum(number):
"""For a given number generates a Verhoeff digit and
returns number + digit"""
c = 0
for i, item in enumerate(reversed(str(number))):
c = verhoeff_table_d[c][verhoeff_table_p[i % 8][int(item)]]
return c
def generate_verhoeff(number):
"""For a given number returns number + Verhoeff checksum digit"""
return "%s%s" % (number, calcsum(number))
def validate_verhoeff(number):
"""Validate Verhoeff checksummed number (checksum is last digit)"""
return checksum(number) == 0
import re
import sys
def bug_numbers(commit):
bug_re = re.compile('fixes #([0-9]+)', re.I)
return bug_re.findall(commit)
with open(sys.argv[1]) as f:
bug_numbers = bug_numbers(f.read())
valid = True
for i in bug_numbers:
if not validate_verhoeff(i):
sys.stderr.write('\033[91m!!!!!\033[0m #%s is not a valid bug number\n' % i)
valid = False
if valid:
sys.exit(0)
else:
sys.stderr.write('\033[91mAborting commit\033[0m due to invalid bug number\n')
sys.exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment