我有什麼辦法檢查32位網絡掩碼是否有效或不使用按位運算符?有效網絡掩碼的c代碼
我必須從msb端檢查'1'是否在連續流中。 例如11111111.0.0.0(255.0.0.0)有效 但11111101.0.0.0(253.0.0.0)不是。
我有什麼辦法檢查32位網絡掩碼是否有效或不使用按位運算符?有效網絡掩碼的c代碼
我必須從msb端檢查'1'是否在連續流中。 例如11111111.0.0.0(255.0.0.0)有效 但11111101.0.0.0(253.0.0.0)不是。
首先要做的是檢查網絡掩碼非零(一個討厭的邊緣情況)。鑑於這是好的,你需要採取按位反轉。
uint32_t y = ~x;
然後添加一個
uint32_t z = y + 1;
然後,如果x
是適當的網絡掩碼,將有最多1位在此設置。
爲了測試這一點,只需和z
與z - 1
,這恰好是y
。如果一切正常,結果將爲零,否則爲零。
valid = (z & y) == 0;
要檢查是否存在無效的子網掩碼,你可以使用下面的簡單算法:
mask & (~mask >> 1)
這將計算爲1爲一個有效的網絡掩碼無效的子網掩碼和0。
一個有效的網絡掩碼不能在其右邊有一個零。所有零必須在其右邊必須有另一個零,或者位爲0.如果您將一個網絡掩碼的補碼(〜)與其右邊的一個相加,並將其右移一位,你會將網絡掩碼中的一個與網絡掩碼的移位補碼中的一個對齊。並且將這兩個值一起產生一個表示無效網掩碼的值。
如果按照網絡字節順序應用此算法,請務必使用ntohl()將網絡掩碼轉換爲主機字節順序。此外,如果您希望排除它們,則需要對0xffffffff和0x00000000進行特殊檢查。
注意:由於C對運算符的優先級和關聯性規則,算法中顯示的括號不是必需的,但是我已經添加了它們來使代碼更易於理解,以防您不總是記住優先級和關聯性規則。
int is_netmask_valid(uint32_t mask)
{
if (mask == 0) return 0;
if (mask & (~mask >> 1)) {
return 0;
} else {
return 1;
}
}
(即將給出相同的答案:-)但是我會使用'unsigned int'或'uint32_t'來避免'z = y + 1'上的未定義溢出行爲。 –
哎呀,是的。大腦今天早上死了,它只是星期一 - 按建議編輯。 –
我有一些不那麼高效的版本,它具有易於理解的優點。你能否解釋_why_這是否有效?即使在紙上塗寫了一些網絡掩碼並在所有值之間寫入所有值,我都無法確定算法背後的數學原理。 – LeSpocky