| 
In response to
Ian Bicking's Python nit, chapter 3
, I commented that I had just used iterating over a string to validate
hardware addresses. 
 Here's my fairly liberal hardware address normalizer thingy that uses
iterating through a string:
 
HEXDIGITS = '0123456789abcdefABCDEF'
MAC_ADDR_LENGTH = 12
def normalize_mac(address):
    """
    Return valid MAC address in our favored format. 
    It is very liberal in what it accepts as there can be any number
    of seperator characters in any combination in the input address.
    Arguments:
        address -- (string) A possible MAC address.
    Returns:
        The possible MAC address in our choosen format (xx:xx:xx:xx:xx:xx)
    Raises:
        TypeError -- if address isn't a string.
        ValueError -- when address isn't a valid MAC address.
    """
    if not isinstance(address, str):
        raise TypeError, "address must be a string"
    seperators = '-:. ' # NOTE: contains space as a seperator
    for sep in seperators:
        address = address.replace(sep, '') 
   
    count = 0 
    for digit in address:
        if digit not in HEXDIGITS:
            err = 'Invalid MAC: Address contains bad digit (%s)' % digit
            raise ValueError, err
        else:
            count = count + 1
            if count > MAC_ADDR_LENGTH: 
                err = 'Invalid MAC: Address too long'
                raise ValueError, err 
    if count < MAC_ADDR_LENGTH:
        err = 'Invalid MAC: Address too short'
        raise ValueError, err 
    address = address.lower()
    parts = [address[i:i+2] for i in range(0, MAC_ADDR_LENGTH, 2)]
    return ':'.join(parts)      
 So yeah, I think iterating over strings is nifty, and eschewing regular
expressions is doubly so. The code once used the following to find bad digits in MAC addresses:
 
    illegal_chars = re.compile(r'[^0-9a-f]', re.IGNORECASE).search
    match = illegal_chars(address)
    if match is not None:
        err = 'Invalid MAC: address contains bad digit (%s)' % match.group()
        raise ValueError, err 
 but I changed it to avoid using a regex. I'm happier that way.
 Take care. |