1. 程式人生 > >python IP格式校驗

python IP格式校驗

    校驗對於web開發同學來說,寫程式碼時是必不可少的。

    不管前端有沒有做校驗,後端還是必須得要做校驗。出於安全性考慮,可以有效的防止sql注入。

    校驗其實是一件很無聊的事情,重複寫著程式碼。所以整理出通用的介面還是蠻有必要的。今天貼出一版python的IP校驗介面,包括IPv4和IPv6的校驗

IPv4:

def validate_ip(ip_str):
    sep = ip_str.split('.')
    if len(sep) != 4:
        return False
    for i,x in enumerate(sep):
        try:
            int_x = int(x)
            if int_x < 0 or int_x > 255:
                return False
        except ValueError, e:
            return False
    return True

IPv4校驗較簡單,原理如上述程式碼,以“.”分割一下,然後對每位進行範圍校驗,不在0~255的就校驗失敗。

IPv6:

IPv6地址大小為128位。首選的 IPv6 地址表示為:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx,其中每個 x 是代表一個 4 位的十六進位制數字。

v6相比較v4的話,稍微複雜。首先,我們要明白IPv6有哪些格式都屬於合法的:

1. 正常情況

FFFF:0000:0000:FFFF:FFFF:FFFF:FFFF;FFFF

2.前導0省略:

如:

FFFF:0000:0000:0FFF:FFFF:FFFF:FFFF;FFFF,可以寫成:

FFFF:0:0:FFF:FFFF:FFFF:FFFF;FFFF

3.雙冒號形式:

如:

FFFF:0000:0000:0FFF:FFFF:FFFF:FFFF;FFFF,可以寫成:

FFFF::0FFF:FFFF:FFFF:FFFF;FFFF

4.相容IPv4的IPv6格式:

如:

FFFF:0000:0000:0FFF:FFFF:FFFF:192.168.0.1也是合法的。

有了上面這些合法的格式,貼上程式碼:

# -*- coding:utf-8 -*-
import os
import sys
import re

def validate_ip(ip_str):
    '''
    Validate a hexidecimal IPv6 ip address.
    :param ip_str: String to validate as a hexidecimal IPv6 ip address.
    :type ip_str: str
    :returns: ``True`` if a valid hexidecimal IPv6 ip address,
              ``False`` otherwise.
    :raises: TypeError
    '''
    #:Regex for validating an IPv6 in hex notation
    # _HEX_RE_1 = re.compile(r'^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$')
    _HEX_RE = re.compile(r'^:{0,1}([0-9a-fA-F]{0,4}:){0,7}[0-9a-fA-F]{0,4}:{0,1}$')
    # _HEX_RE = re.compile(r'^([0-9a-fA-F]{0,4}:){2,7}[0-9a-fA-F]{0,4}:{0,1}$')

    #:Regex for validating an IPv6 in dotted-quad notation
    _DOTTED_QUAD_RE = re.compile(r'^:{0,1}([0-9a-fA-F]{0,4}:){2,6}(\d{1,3}\.){3}\d{1,3}$')
    if _HEX_RE.match(ip_str):
        if ':::' in ip_str:
            return False
        if '::' not in ip_str:
            halves = ip_str.split(':')
            return len(halves) == 8 and halves[0] != '' and halves[-1] != ''
        halves = ip_str.split('::')
        if len(halves) != 2:
            return False
        if halves[0] != '' and halves[0][0] == ':':
            return False
        if halves[-1] != '' and halves[-1][-1] == ':':
            return False
        return True

    if _DOTTED_QUAD_RE.match(ip_str):
        if ':::' in ip_str:
            return False
        if '::' not in ip_str:
            halves = ip_str.split(':')
            return len(halves) == 7 and halves[0] != ''
        halves = ip_str.split('::')
        if len(halves) > 2:
            return False
        hextets = ip_str.split(':')
        quads = hextets[-1].split('.')
        for q in quads:
            if int(q) > 255 or int(q) < 0:
                return False
        return True
    return False


原理也比較簡單,先利用正則匹配,然後在考慮其他特殊情況。

結束!!!