IP头校验和

IP头校验和计算时将校验和字段预留为0,然后每16bit累加一次,直到计算完成。如果最后剩下一个单数字节,前面补0再累加。计算结果在返回前取反。
校验时不处理校验和位,吧所有数据累加一遍,如果结果为0xFFFF或者0x0000(取决于你是不是使用同一个函数计算,也就是最后一步是否取反)表明正确(很神奇?)其实就是一个数加上这个数的反码结果是一串1,这个方法同样适用于TCP,UDP等等其他协议的计算。参考这个:http://blog.chinaunix.net/u/12313/showart_176114.html
下面是Java实现代码

    public int csum(ByteBuffer buff) {
        int sum = 0;
        while (buff.remaining() > 1) {
            sum += buff.getShort() & 0xFFFF;
        }
        if (buff.remaining() > 0) {
            sum += buff.get() & 0xFF;
        }
        while (sum >>> 16 != 0) {
            sum = (sum & 0xFFFF) + (sum >>> 16);
        }
        return (~sum) & 0xFFFF;
    }

测试:

    @Test
    public void testCsum() {
        System.out.println("csum");
        byte[] buf = new byte[]{
            (byte) 0x45, (byte) 0x00,
            (byte) 0x00, (byte) 0x88,
            (byte) 0x00, (byte) 0x23,
            (byte) 0x00, (byte) 0x00,
            (byte) 0xff, (byte) 0x2f,
            (byte) 0x00, (byte) 0x00,
            (byte) 0xc0, (byte) 0xa8,
            (byte) 0x64, (byte) 0xfd,
            (byte) 0xc0, (byte) 0xa8,
            (byte) 0x64, (byte) 0xfc
        };
        IPHeader instance = new IPHeader();
        int expResult = 0x6fd9;
        int result = instance.csum(ByteBuffer.wrap(buf));
        System.out.printf("0x%04x%n",result);
        System.out.printf("0x%04x%n",result&((~result)&0xFFFF));
        assertEquals(expResult, result);
    }
>_<|| 我手贱!!这个有问题!绝对有问题!!一般般啦,真的很一般般。还不错哦~小表扬一下!GJ!乃就是新世界的神様了,快去拯救世界吧! (No Ratings Yet)
Loading...

一人吐槽

  1. int说道:
    骑着 IceWeasel 3.0.6 IceWeasel 3.0.6 和 Debian GNU/Linux Debian GNU/Linux
    Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.11) Gecko/2009061212 Iceweasel/3.0.6 (Debian-3.0.6-1)

    用libnet就不用计算crc了!不知道py有没有libnet的portage

春菜 对话 相声
双击调戏
双击调戏