<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>I&#039;m frankyue &#187; C</title>
	<atom:link href="http://frankyue.me/tag/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://frankyue.me</link>
	<description>VIIV 535</description>
	<lastBuildDate>Sat, 27 Mar 2010 07:11:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>zh</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>关于checksum</title>
		<link>http://frankyue.me/2008/10/%e5%85%b3%e4%ba%8echecksum/</link>
		<comments>http://frankyue.me/2008/10/%e5%85%b3%e4%ba%8echecksum/#comments</comments>
		<pubDate>Wed, 15 Oct 2008 04:58:18 +0000</pubDate>
		<dc:creator>frankyue</dc:creator>
				<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://frankyue.cn/?p=136</guid>
		<description><![CDATA[       最近一段时间很忙没来写东西了，发下最近写的一个东西，一个UDP的CHECKSUM（校验和）。

在网络传送的数据包为了保证传送正确都含有效验字段，IP、arp、tcp等每个数据段都有自己的效验和。

       刚开始找来个现成的IP数据包的校验和，不过后来才知道UDP和IP的校验和还有差别，所有又重新来
UDP报文的头由 发送端端口(2字节)，目标端口(2字节)，UDP包长度(2字节)，校验和(2字节)4部分组成。
校验和的值由伪IP头，UDP头和UDP数据三部分的字串以16bit作单位进行相加后取反码（one’s complement ）得到。若数据长度为基数，则最后补一个字节的0。

        老师要求都用C语言写，古老的语言阿，都N年没用了，不过嵌入式的东西都用他来完成，虽然我还没接触到嵌入式的东西，用了些之前从没用过的unsigned short,取反等操作，都是接触底层的东西按照网上了解的算法得出如下：
#include
#define INDEXUDPLANG 12
void ChecksumForudp(unsigned short *str1,unsigned short *str2,int len)
{
	unsigned short	*sbuf;
	int	 i;
	unsigned int	hi=0, lo=0, hicarry, locarry;
	sbuf = (unsigned short *) str1;
	for (i = 0 ; i < len ; i [...]]]></description>
			<content:encoded><![CDATA[<p>       最近一段时间很忙没来写东西了，发下最近写的一个东西，一个UDP的CHECKSUM（校验和）。</p>
<blockquote><p>
在网络传送的数据包为了保证传送正确都含有效验字段，IP、arp、tcp等每个数据段都有自己的<a href="http://it.icxo.com/htmlnews/2004/07/20/270977.htm">效验和</a>。</p>
</blockquote>
<p>       刚开始找来个现成的IP数据包的校验和，不过后来才知道UDP和IP的校验和还有差别，所有又重新来</p>
<blockquote><p>UDP报文的头由 发送端端口(2字节)，目标端口(2字节)，UDP包长度(2字节)，校验和(2字节)4部分组成。<br />
校验和的值由伪IP头，UDP头和UDP数据三部分的字串以16bit作单位进行相加后取反码（one’s complement ）得到。若数据长度为基数，则最后补一个字节的0。</p>
</blockquote>
<p>        老师要求都用C语言写，古老的语言阿，都N年没用了，不过嵌入式的东西都用他来完成，虽然我还没接触到嵌入式的东西，用了些之前从没用过的unsigned short,取反等操作，都是接触底层的东西按照网上了解的算法得出如下：</p>
<blockquote><p>#include<stdio.h><br />
#define INDEXUDPLANG 12<br />
void ChecksumForudp(unsigned short *str1,unsigned short *str2,int len)<br />
{<br />
	unsigned short	*sbuf;<br />
	int	 i;<br />
	unsigned int	hi=0, lo=0, hicarry, locarry;</p>
<p>	sbuf = (unsigned short *) str1;</p>
<p>	for (i = 0 ; i < len ; i += 2)<br />
	{<br />
		if( i != INDEXUDPLANG )<br />
		{<br />
			if( i != len-2)<br />
			{<br />
		    	hi += sbuf[i];<br />
	    		lo += sbuf[i+1];<br />
	    	}<br />
	    	else<br />
	    	{<br />
	    		hi += sbuf[i];<br />
   				lo += sbuf[i+1];<br />
	    	}<br />
    	}<br />
 	   else<br />
 	   {<br />
	   		hi +=sbuf[i]+sbuf[i];//加两次包长<br />
	   		lo +=sbuf[i+1]+sbuf[i+1];//加两次包长<br />
    	}<br />
	}</p>
<p>	lo += 0&#215;11;						//加UDP协议值0&#215;0011</p>
<p>	hicarry = hi >> 8;				//提取进位<br />
	locarry = lo >> 8;</p>
<p>	while (hicarry || locarry)<br />
	{								//将进位循环加回<br />
	    hi = (hi &#038; 0xFF) + locarry;<br />
	    lo = (lo &#038; 0xFF) + hicarry;<br />
	    hicarry = hi >> 8;<br />
	    locarry = lo >> 8;</p>
<p>	}</p>
<p>	sbuf[INDEXUDPLANG]=		(~hi) &#038; 0xff;				//将checksum高位放入<br />
	sbuf[INDEXUDPLANG+1]=	(~lo) &#038; 0xff;				//将checksum低位放入</p>
<p>	str2 = str1;<br />
}<br />
int main()<br />
{<br />
	//unsigned short str[]= {0&#215;0a,0&#215;99,0&#215;35,0&#215;0f,0&#215;0a,0&#215;00,0&#215;00,0xac,0&#215;20,0xdb,0&#215;23,0xf1,0&#215;00,0&#215;0b,0&#215;00,0&#215;00,0&#215;18,0&#215;00,0&#215;23};<br />
	unsigned short str[]= {0&#215;0a,0&#215;99,0&#215;35,0&#215;0f,0&#215;0a,0&#215;00,0&#215;00,0xac,0&#215;20,0xdb,0&#215;23,0xf1,0&#215;00,0&#215;7b,0&#215;00,0&#215;00,0&#215;0a,0&#215;00,0&#215;21,0&#215;12<br />
	,0&#215;01,0&#215;10,0&#215;13,0&#215;58,0&#215;04,0&#215;80,0&#215;83,0xd4,0&#215;60,0&#215;04,0&#215;81,0&#215;83,0xd4,0&#215;60,0&#215;02,0&#215;82,0&#215;00,0&#215;02,0&#215;83,0&#215;05,0&#215;02,0&#215;84,0&#215;01,0&#215;80<br />
	,0&#215;80,0&#215;83,0&#215;99,0&#215;81,0xea,0xa9};<br />
	unsigned short *str1,*str2;<br />
	str1=str;<br />
	int i = 0;<br />
	ChecksumForudp(str1,str2,50);</p>
<p>	printf(&#8220;%x\n&#8221;,str1[12]);<br />
	printf(&#8220;%x\n&#8221;,str1[13]);<br />
	printf(&#8220;ANSWER IS 35B8!\n&#8221;);<br />
}
</p>
</blockquote>
<p>还有个BUG，就是UDP包最长为65535，在进行加法hi和lo是会不会超过int 长度，在得到hicarry和locarry会不会使数据丢失，总想不明白会不会，自己数学太差了！我再琢磨琢磨！</p>
<p>得去装个代码查看插件，这里发出来的格式都变了郁闷</p>
]]></content:encoded>
			<wfw:commentRss>http://frankyue.me/2008/10/%e5%85%b3%e4%ba%8echecksum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
