CRC、校验和与路由算法伪代码
CRC 生成
输入:
dataBits:原始数据 bit 串,长度为。 generator:生成多项式 bit 串,最高位和最低位为 1,长度为。
输出:原始数据后附
function crcEncode(dataBits, generator):
r = length(generator) - 1
work = dataBits followed by r zeros
for i from 0 to length(dataBits) - 1:
if work[i] == 1:
for j from 0 to r:
work[i + j] = work[i + j] XOR generator[j]
remainder = last r bits of work
return dataBits followed by remainder关键不变量:处理到位置 i 后,该位置及其左侧已经被消为 0,不再参与后续除法。
接收端验证:
function crcCheck(codeword, generator):
work = copy(codeword)
r = length(generator) - 1
for i from 0 to length(codeword) - r - 1:
if work[i] == 1:
for j from 0 to r:
work[i + j] = work[i + j] XOR generator[j]
return last r bits of work are all zero模 2 减法和加法都使用 XOR,不产生借位或进位。
16 bit Internet Checksum
输入为任意字节串。奇数字节时末尾临时补 0,按网络字节序组成 16 bit 字。
function internetChecksum(bytes):
if length(bytes) is odd:
append one zero byte for calculation
sum = 0
for each 16-bit word in bytes:
sum = sum + word
while sum > 0xFFFF:
sum = (sum AND 0xFFFF) + (sum >> 16)
return bitwiseComplement(sum) AND 0xFFFF接收端把校验和字段也纳入相加:
function checksumValid(bytesIncludingChecksum):
sum = onesComplementSum(bytesIncludingChecksum)
return sum == 0xFFFFUDP、TCP 计算前要拼接网络层伪首部;IPv4 首部校验和只覆盖 IPv4 首部,并把 Checksum 字段先置 0。
最长前缀匹配
每条路由包含:
(prefix, prefixLength, nextHop, interface, preferenceData)基础最长前缀过程:
function longestPrefixMatch(destination, routingTable):
best = NONE
for each route in routingTable:
mask = maskFromLength(route.prefixLength)
if (destination AND mask) == route.prefix:
if best is NONE or route.prefixLength > best.prefixLength:
best = route
else if route.prefixLength == best.prefixLength:
best = selectByRoutePreference(best, route)
return best先按前缀长度选择最具体路由;只有前缀长度相同时,才比较协议优先级、度量或等价多路径规则。默认路由 /0 作为最低前缀长度候选。
Dijkstra 链路状态算法
输入:非负链路代价图 source。
function dijkstra(graph, source):
for each vertex v:
dist[v] = INFINITY
prev[v] = NONE
confirmed[v] = false
dist[source] = 0
repeat |V| times:
u = unconfirmed vertex with minimum dist[u]
if u does not exist or dist[u] == INFINITY:
break
confirmed[u] = true
for each neighbor v of u:
if confirmed[v] == false:
candidate = dist[u] + cost(u, v)
if candidate < dist[v]:
dist[v] = candidate
prev[v] = u
return dist, prev关键不变量:选入 confirmed 的结点,其从源点出发的最短距离已经确定。链路代价必须非负。
恢复到目标 t 的路径:
path = empty list
u = t
while u is not NONE:
prepend u to path
u = prev[u]路由器生成转发表时,需要从恢复路径中取源结点之后的第一个结点作为下一跳。
距离向量更新
结点 x 已知到每个邻居 v 的直连代价 cost[x][v],并收到邻居通告的距离 DV[v][y]。
function recomputeDistanceVector(x):
changed = false
for each destination y:
bestDistance = INFINITY
bestNextHop = NONE
for each neighbor v of x:
candidate = cost[x][v] + DV[v][y]
if candidate < bestDistance:
bestDistance = candidate
bestNextHop = v
if bestDistance != DV[x][y] or bestNextHop != nextHop[x][y]:
DV[x][y] = bestDistance
nextHop[x][y] = bestNextHop
changed = true
if changed:
send DV[x] to neighbors according to update policy核心关系:
IPv4 分片
输入:原始数据报 datagram 和输出链路 MTU。
function fragmentIPv4(datagram, MTU):
H = datagram.headerLengthBytes
D = datagram.totalLength - H
if datagram.totalLength <= MTU:
return [datagram]
if datagram.DF == 1:
drop datagram
send ICMP fragmentation-needed information // 王道口径:ICMP 终点不可达报文
return []
maxPayload = floor((MTU - H) / 8) * 8
fragments = empty list
start = 0
while start < D:
payloadLength = min(maxPayload, D - start)
fragment = copy relevant IPv4 header fields
fragment.identification = datagram.identification
fragment.offset = start / 8
fragment.MF = (start + payloadLength < D)
fragment.payload = datagram.payload[start : start + payloadLength]
fragment.totalLength = H + payloadLength
recompute fragment.headerChecksum
append fragment to fragments
start = start + payloadLength
return fragments若输入本身已是一个分片,再次分片时要把新片 Offset 加到原 Offset 对应的原数据位置,并正确继承最终 MF 语义。
二层交换机自学习与转发
function processFrame(frame, incomingPort, vlan):
table[(vlan, frame.sourceMAC)] = (incomingPort, currentTime)
if frame.destinationMAC is broadcast or multicast:
flood to all forwarding ports in vlan except incomingPort
return
entry = table[(vlan, frame.destinationMAC)]
if entry does not exist or entry is expired:
flood to all forwarding ports in vlan except incomingPort
else if entry.port == incomingPort:
filter frame
else:
forward frame only to entry.port交换机从源 MAC 学习入口,从目的 MAC 决定出口。学习表按 VLAN 隔离并随时间老化。
手算检查
- CRC:生成多项式最高次数等于补 0 位数和余数长度。
- 校验和:最高位进位必须回卷,最后再逐位取反。
- 最长前缀:先列出全部匹配项,再选前缀最长项。
- Dijkstra:每轮只确定一个当前最小未确定结点,再松弛其邻边。
- 距离向量:每个候选都由“到邻居代价 + 邻居到目的距离”组成。
- 分片:Offset 按 8 B,Total Length 要重新加首部,所有分片共用 Identification。
- 交换机:学习源地址,查找目的地址;未知单播只在同 VLAN 泛洪。
链接
- 上级索引:计算机网络伪代码附录
- 差错检测:3.3.1 检错编码
- 路由算法:4.4.1 路由算法
- IPv4 分片:4.2.1 IPv4 分组与分片
- 交换机学习:3.8 网桥与以太网交换机