﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-★Snowhill ★-随笔分类-C/C++</title><link>http://www.cppblog.com/snowhill/category/3364.html</link><description>&lt;font color=#5555aa &gt;&lt;b&gt; 颠沛必于是，造次必于是！&lt;/b&gt;&lt;/font&gt;</description><language>zh-cn</language><lastBuildDate>Thu, 22 May 2008 07:31:12 GMT</lastBuildDate><pubDate>Thu, 22 May 2008 07:31:12 GMT</pubDate><ttl>60</ttl><item><title>硬盘分区表之一（转）</title><link>http://www.cppblog.com/snowhill/archive/2007/11/09/36202.html</link><dc:creator>snowhill</dc:creator><author>snowhill</author><pubDate>Fri, 09 Nov 2007 05:29:00 GMT</pubDate><guid>http://www.cppblog.com/snowhill/archive/2007/11/09/36202.html</guid><wfw:comment>http://www.cppblog.com/snowhill/comments/36202.html</wfw:comment><comments>http://www.cppblog.com/snowhill/archive/2007/11/09/36202.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/snowhill/comments/commentRss/36202.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/snowhill/services/trackbacks/36202.html</trackback:ping><description><![CDATA[&nbsp;
<p align=center><strong><span>深入浅出硬盘分区表</span></strong><span><br><br></span><span>作者：武汉市中国地质大学</span><span> <span><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#121;&#116;&#95;&#53;&#48;&#48;&#48;&#64;&#115;&#111;&#104;&#117;&#46;&#99;&#111;&#109;"><span><span>印涛</span></span><span>,</span><span><span>秦剑</span></span></a><br><br>&nbsp;&nbsp;&nbsp; </span></span><span>人们在使用电脑时，有时由于异常操作，有时由于病毒侵袭，会导致某个分区消失或硬盘无法启动。究其原因，就是硬盘分区表受损。硬盘分区表可以说是支持硬盘正常工作的骨架</span><span>.</span><span>操作系统正是通过它把硬盘划分为若干个分区</span><span>,</span><span>然后再在每个分区里面创建文件系统</span><span>,</span><span>写入数据文件</span><span>.</span><span>本文主要讲述的是分区表的位置</span><span>,</span><span>结构以及各个分区表是如何链接起来的</span><span>.</span><span>当掌握了这些知识后</span><span>,</span><span>即使分区表受到破坏</span><span>,</span><span>一样也可以根据残存的数据手工修复分区表，从而修复分区。</span><span><br><br></span><strong><span>一</span></strong><strong><span>.</span></strong><strong><span>分区表的位置及识别标志</span></strong><span><br>&nbsp;&nbsp;&nbsp; </span><span>分区表一般位于硬盘某柱面的</span><span>0</span><span>磁头</span><span> 1</span><span>扇区</span><span>.</span><span>而第</span><span>1</span><span>个分区表</span><span>(</span><span>也即主分区表</span><span>)</span><span>总是位于</span><span>&nbsp;<br>(0</span><span>柱面</span><span>,1</span><span>磁头</span><span>,1</span><span>扇区</span><span>),</span><span>剩余的分区表位置可以由主分区表依次推导出来．分区表有</span><span>64</span><span>个字节</span><span>,</span><span>占据其所在扇区的</span><span>[441-509]</span><span>字节</span><span>.</span><span>要判定是不是分区表</span><span>,</span><span>就看其后紧邻的两个字节</span><span>(</span><span>也即</span><span>[510-511])</span><span>是不是</span><span> "55AA",</span><span>若是</span><span>,</span><span>则为分区表．</span><span><br><br></span><strong><span>二</span></strong><strong><span>.</span></strong><strong><span>分区表的结构</span></strong><span><br></span><span>分区表由</span><span>4</span><span>项组成，每项</span><span>16</span><span>个字节</span><span>.</span><span>共</span><span>4&#215;16 = 64</span><span>个字节．每项描述一个分区的基本信息</span><span>.</span><span>每个字节的含义如下</span><span>:<br></span><span>分区表项含义</span></p>
<table cellSpacing=0 cellPadding=0 width="88%" border=1>
    <tbody>
        <tr>
            <td width="50%">
            <p align=center><span>字节</span></p>
            </td>
            <td width="50%">
            <p align=center><span>含义</span></p>
            </td>
        </tr>
        <tr>
            <td width="50%">
            <p align=center><span>0</span></p>
            </td>
            <td width="50%">
            <p align=left><span>Activeflag.</span><span>活动标志</span><span>.</span><span>若为</span><span>0x80H,</span><span>则表示该分区为活动分区</span><span>.</span><span>若为</span><span>0x00H,</span><span>则表示该分区为非活动分区</span><span>.</span></p>
            </td>
        </tr>
        <tr>
            <td width="50%">
            <p align=center><span>1,2,3</span></p>
            </td>
            <td width="50%">
            <p align=left><span>该分区的起始磁头号</span><span>,</span><span>扇区号</span><span>,</span><span>柱面号磁头号</span><span> -- 1</span><span>字节</span><span>, </span><span>扇区号</span><span> -- 2</span><span>字节低</span><span>6</span><span>位</span><span>,</span><span>柱面号</span><span> -- 2</span><span>字节高</span><span>2</span><span>位</span><span> + 3</span><span>字节</span></p>
            </td>
        </tr>
        <tr>
            <td width="50%">
            <p align=center><span>4</span></p>
            </td>
            <td width="50%">
            <p align=left><span>分区文件系统标志：</span><span><br></span><span>分区未用</span><span>: 0x00H. <br></span><span>扩展分区</span><span>: 0x05H, 0x0FH.<br>FAT16</span><span>分区</span><span>: 0x06H.<br>FAT32</span><span>分区</span><span>: 0x0BH, 0x1BH, 0x0CH, 0x1CH.<br>NTFS</span><span>分区</span><span>: 0x07H.</span></p>
            </td>
        </tr>
        <tr>
            <td width="50%">
            <p align=center><span>5,6,7</span></p>
            </td>
            <td width="50%">
            <p align=left><span>该分区的结束磁头号</span><span>,</span><span>扇区号</span><span>,</span><span>柱面号，含义同上</span><span>.</span></p>
            </td>
        </tr>
        <tr>
            <td width="50%">
            <p align=center><span>8,9,10,11</span></p>
            </td>
            <td width="50%">
            <p align=left><span>逻辑起始扇区号。表示分区起点之前已用了的扇区数</span><span>.</span></p>
            </td>
        </tr>
        <tr>
            <td width="50%">
            <p align=center><span>12,13,14,15</span></p>
            </td>
            <td width="50%">
            <p align=left><span>该分区所占用的扇区数</span><span>.</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p align=left><span><br></span><span>分区表项有几个字节比较重要，下面分别阐述之：</span><span> </span></p>
<p align=left><span>1</span><span>、（</span><span>1</span><span>，</span><span>2</span><span>，</span><span>3</span><span>）字节</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>磁头号由（</span><span>1</span><span>）字节</span><span>8</span><span>位表示，其范围为（</span><span>0 -- 28 - 1</span><span>），也即（</span><span>0 </span><span>磁头</span><span>-- 254</span><span>磁头）。</span><span><span>&nbsp;&nbsp; </span></span></p>
<p align=left><span>扇区号由（</span><span>2</span><span>）字节低</span><span>6</span><span>位表示，其范围为（</span><span>0 -- 26 - 1</span><span>），由于扇区号从</span><span>1</span><span>开始，所以其范围是（</span><span>1</span><span>扇区</span><span>-- 63</span><span>扇区）。</span><span><span>&nbsp;&nbsp; </span></span></p>
<p align=left><span>柱面号由（</span><span>2</span><span>）字节高</span><span>2</span><span>位</span><span> + </span><span>（</span><span>3</span><span>）字节，共</span><span>10</span><span>位表示，其范围为（</span><span>0 --2 10 - 1</span><span>），也即（</span><span>0 </span><span>柱面</span><span>-- 1023</span><span>柱面）。</span></p>
<p align=left><span>当柱面号超过</span><span>1023</span><span>时，这</span><span>10</span><span>位依然表示成</span><span>1023</span><span>，需要注意。</span><span><span>&nbsp;&nbsp; </span></span></p>
<p align=left><span>（</span><span>5</span><span>，</span><span>6</span><span>，</span><span>7</span><span>）字节含义同上。</span></p>
<p align=left><span>2</span><span>、（</span><span>8, 9, 10, 11</span><span>）字节</span><span>&nbsp;</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>如果是主分区表，则这</span><span>4 </span><span>个字节表示该分区起始逻辑扇区号与逻辑</span><span>0</span><span>扇区（</span><span>0</span><span>柱面，</span><span>0</span><span>磁头，</span><span>1</span><span>扇区）之差。如果非主分区表，</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>则这</span><span>4 </span><span>个字节要么表示该分区起始逻辑扇区号与扩展分区起始逻辑扇区号之差，要么为</span><span>63</span><span>。详细情况在后面有所阐述。</span><span>&nbsp;</span></p>
<p align=left><span>&nbsp;</span></p>
<p align=left><span>注意：</span><span> </span></p>
<p align=left><span>1</span><span>、扇区上的字节是按左边低位，右边高位的顺序排列的。所以在取值时，需要把字节再反一下，让高位字节在左边，低位字节在右边，</span></p>
<p align=left><span>这一点在读取逻辑起始扇区号和分区大小时需要注意。举个例子</span><span>:</span><span>第一项的逻辑起始扇区为</span><span>(3F 00 00 00)</span><span>，转换为十进制前要先反一下字</span></p>
<p align=left><span>节顺序，为（</span><span>00 00 00 3F</span><span>）然后在转换为十进制，即</span><span>63 .</span><span>同理分区大小为（</span><span>3F 04 7D 00</span><span>），先反为（</span><span>00 7D 04 3F</span><span>）再转换为十进制，</span></p>
<p align=left><span>即</span><span>8193087</span><span>。</span></p>
<p align=left><span>&nbsp;</span></p>
<p align=left><span>2</span><span>、逻辑扇区号与（柱面，磁头，扇区）的相互转换：</span></p>
<p align=left><span>令</span><span>L = </span><span>逻辑扇区号，</span><span>C = </span><span>柱面号，</span><span>H = </span><span>磁头号，</span><span>S = </span><span>扇区号。</span></p>
<p align=left><span>每道扇区数</span><span> =&nbsp;63</span></p>
<p align=left><span>每柱面磁头数</span><span> = 255</span></p>
<p align=left><span>每柱面扇区数</span><span> = </span><span>每道扇区数</span><span>* </span><span>每柱面磁头数</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>= 63 &#215; 255</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;= 16065</span></p>
<p align=left><span>柱面号下标从</span><span>0</span><span>开始。磁头号</span><span>[0 -- 254]</span><span>，扇区号</span><span>[1 -- 63]</span><span>。</span></p>
<p align=left><span>逻辑扇区号下标也从</span><span>0</span><span>开始。</span></p>
<p align=left><span>(</span><span>柱面，磁头，扇区</span><span>)</span><span>转换成逻辑扇区号的公式为：</span></p>
<p align=left><span>L = C&#215;16065 + H &#215;63 + S - 1 ;</span></p>
<p align=left><span>比如（</span><span>1</span><span>柱面，</span><span>1</span><span>磁头，</span><span>1</span><span>扇区），其逻辑扇区号为：</span></p>
<p align=left><span>L = 1&#215;16065 + 1&#215;63 + 1 - 1</span></p>
<p align=left><span>= 16128</span></p>
<p align=left><span>逻辑扇区号转换成</span><span>(</span><span>柱面，磁头，扇区</span><span>) </span><span>公式为：</span></p>
<p align=left><span>C = L / 16065</span></p>
<p align=left><span>H = (L % 16065) / 63</span></p>
<p align=left><span>S = (L % 16065) % 63 + 1</span></p>
<p align=left><span>比如逻辑扇区号</span><span> 16127</span><span>：</span></p>
<p align=left><span>C = 16127 / 16065 = 1</span></p>
<p align=left><span>H = (16127 % 16065) / 63 = 0</span></p>
<p align=left><span>S = (16127 % 16065) % 63 + 1 = 63</span></p>
<p align=left><span>即（</span><span>1</span><span>柱面，</span><span>0</span><span>磁头，</span><span>63</span><span>扇区）</span></p>
<p align=left><span>&nbsp;</span></p>
<p align=left><span>3</span><span>、分区表上有四项，每一项表示一个分区，所以一个分区表最多只能表示</span><span>4</span><span>个分区。主分</span><span> </span></p>
<p align=left><span>区表上的</span><span>4</span><span>项用来表示主分区和扩展分区的信息。因为扩展分区最多只能有一个，所以硬盘</span><span> </span></p>
<p align=left><span>最多可以有四个主分区或者三个主分区，一个扩展分区。余下的分区表是表示逻辑分区的。</span><span> </span></p>
<p align=left><span>这里有必要阐述一点：逻辑区都是位于扩展分区里面的，并且逻辑分区的个数没有限制。</span></p>
<p align=left><span>&nbsp;</span></p>
<p align=left><span>4</span><span>、分区表所在扇区通常在（</span><span>0</span><span>磁头，</span><span>1</span><span>扇区），而该分区的开始扇区通常位于（</span><span>1</span><span>磁头，</span><span>1</span><span>扇区），中间隔了</span><span>63 </span><span>个隐藏扇区。</span></p>
<p align=left><span>&nbsp;</span></p>
<p align=left><strong><span>三</span></strong><strong><span>.</span></strong><strong><span>分区表链的查找</span></strong><span><br>&nbsp;</span><span>　分区表链实际上相当于一个单向链表结构。第一个分区表，也即主分区表，可以有一项</span><span> </span><span>描述扩展分区。而这一项就相当于指针，指向扩展分区。然后我们根据该指针来到扩展分</span><span> </span><span>区起始柱面的</span><span>0</span><span>头</span><span>1</span><span>扇区，找到第二个分区表。对于该分区表，通常情况下：第一项描述了</span><span> </span><span>扩展分区中第一个分区的信息，第二项描述下一个分区</span><span>,</span><span>而这第二项就相当于指向第二个分</span><span> </span><span>区的指针，第三项，第四项一般均为</span><span>0</span><span>。我们可以根据该指针来到扩展分区中第二个分区起</span><span> </span><span>始柱面的</span><span>0</span><span>头</span><span>1</span><span>扇区，找到第三个分区表。以此类推，只到最后一个分区表。而最后一个分</span><span> </span><span>区表只有第一项有信息</span><span>,</span><span>余下三项均为</span><span>0.</span><span>相当于其指针为空</span><span>.</span><span>所以只要找到了一个分区表就可</span><span> </span><span>以推导找出其后面所有分区表。不过该分区表前面的分区表就不好推导出来了。但令人高兴</span><span> </span><span>的是这个链表的头节点，也即主分区表的位置是固定的位于（</span><span>0</span><span>柱面</span><span>, 0</span><span>磁头</span><span>, 1</span><span>扇区）处，</span><span> </span><span>我们可以很轻易的找到它，然后把剩下的所有分区表一一找到。</span><span> <br></span><span>以笔者的硬盘为例</span><span>:</span><span>一个主分区（</span><span>C</span><span>盘）</span><span>, </span><span>一个扩展分区</span><span>.</span><span>扩展分区中有两个逻辑分区（</span><span>D</span><span>盘</span><span>,E</span><span>盘）其分区表链示意图如下</span><span>:<br><br></span><span>图一</span><span> </span><span>分区表链示意图</span><span> <br><br>(</span><span>一</span><span>).</span><span>读取（</span><span>0</span><span>柱面，</span><span>0</span><span>磁头，</span><span>1</span><span>扇区）处</span><span>C</span><span>盘的主分区表：</span><span> </span></p>
<p align=left><span>&nbsp;[80 01 01 00 0B FE 7F FD 3F 00 00 00 3F 04 7D 00 ]<span>&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;</span></span></p>
<p align=left><span>&nbsp;[00 00 41 FE 0F FE FF FF 7E 04 7D 00 1F 2C B4 00 ]</span></p>
<p align=left><span>&nbsp;</span></p>
<p align=left><span>[00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ]</span></p>
<p align=left>&nbsp;</p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp; </span>[00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ]</span></p>
<p align=left><span>第一项：</span></p>
<p align=left><span>（</span><span>80</span><span>）（</span><span>01 01 00</span><span>）（</span><span>0B</span><span>）（</span><span>FE 7F FD </span><span>）（</span><span>3F 00 00 00 </span><span>）（</span><span>3F 04 7D 00</span><span>）</span></p>
<p align=left><span>描述的是</span><span>C</span><span>盘的情况。</span></p>
<p align=left><span>1.</span><span>（</span><span>80</span><span>）：表示</span><span>C</span><span>盘为活动分区。即系统会从</span><span>C</span><span>盘启动。</span></p>
<p align=left><span>2.</span><span>（</span><span>01 01 00</span><span>）：表示</span><span>C</span><span>盘的起始扇区为（</span><span>0</span><span>柱面，</span><span>0</span><span>磁头，</span><span>1</span><span>扇区）。</span></p>
<p align=left><span>3.</span><span>（</span><span>0B</span><span>）：表示</span><span>C</span><span>盘的文件系统为</span><span>FAT32</span><span>。</span></p>
<p align=left><span>4</span><span>．（</span><span>FE 7F FD</span><span>）：</span></p>
<p align=left><span>(FE) 16&nbsp;=&nbsp;(254) 10&nbsp;(7F) 16&nbsp;=&nbsp;(0111 1111) 2&nbsp;(FD) 16&nbsp;=&nbsp;(1111 1101) 2</span></p>
<p align=left><span>磁头号：</span><span>(254) 10</span><span>；</span></p>
<p align=left><span>扇区号：</span><span>(11 1111) 2&nbsp;=&nbsp;(63) 10.</span></p>
<p align=left><span>柱面号：</span><span>(01 1111 1101) 2&nbsp;=&nbsp;(509) 10</span></p>
<p align=left><span>故</span><span>C</span><span>盘结束扇区为（</span><span>509</span><span>柱面，</span><span>254</span><span>磁头，</span><span>63</span><span>扇区）。</span></p>
<p align=left><span>5.</span><span>（</span><span>3F 00 00 00</span><span>）：</span></p>
<p align=left><span>反向，</span><span>(00 00 00 3F) 16&nbsp;=&nbsp;(63) 10,</span><span>为</span><span>C</span><span>盘起始逻辑扇区号与逻辑</span><span>0</span><span>扇区号之差。表示</span><span>C</span><span>盘前面已有</span><span>63</span><span>个扇区，这</span><span>63</span><span>个扇区为系统隐藏扇区。</span></p>
<p align=left><span>6. (3F 04 7D 00)</span><span>：</span></p>
<p align=left><span>反向，</span><span>(00 7D 04 3F) 16&nbsp;=&nbsp;(8193087) 10</span><span>。表明</span><span>C</span><span>盘有</span><span>8193087</span><span>个扇区。即（</span><span>0</span><span>柱面，</span><span>1</span><span>磁头，</span><span>1</span><span>扇区）至（</span><span>509</span><span>柱面，</span><span>254</span><span>磁头，</span><span>63</span><span>扇区）</span></p>
<p align=left><span>共有</span><span>8193087</span><span>个扇区。</span></p>
<p align=left><span>第二项：</span></p>
<p align=left><span>(00</span><span>）（</span><span>00 41 FE</span><span>）（</span><span>0F</span><span>）（</span><span>FE FF FF</span><span>）（</span><span>7E 04 7D 00</span><span>）（</span><span>1F 2C B4 00</span><span>）</span></p>
<p align=left><span>描述的是扩展分区的情况。</span></p>
<p align=left><span>1. (00): </span><span>表示该分区不是活动分区。</span></p>
<p align=left><span>2. (00 41 FE):</span></p>
<p align=left><span>(00) 16&nbsp;=&nbsp;(0) 10</span><span>　</span><span> (41) 16&nbsp;=&nbsp;(0100 0001) 2&nbsp;(FE) 16&nbsp;=&nbsp;(1111 1110) 2</span></p>
<p align=left><span>磁头号：</span><span>(0) 10</span><span>；</span></p>
<p align=left><span>扇区号：</span><span>(00 0001) 2&nbsp;=&nbsp;(1) 10.</span></p>
<p align=left><span>柱面号：</span><span>(01 1111 1110) 2&nbsp;=&nbsp;(510) 10</span></p>
<p align=left><span>所以扩展分区的起始扇区为（</span><span>510</span><span>柱面，</span><span>0</span><span>磁头，</span><span>1</span><span>扇区）。</span></p>
<p align=left><span>3. (0F): </span><span>表示该分区为扩展分区。</span></p>
<p align=left><span>4. (FE FF FF):</span></p>
<p align=left><span>(FE) 16&nbsp;=&nbsp;(254) 10&nbsp;(FF) 16&nbsp;=&nbsp;(1111 1111) 2&nbsp;(FF) 16&nbsp;=&nbsp;(1111 1111) 2;</span></p>
<p align=left><span>磁头号：</span><span>(254) 10</span><span>；</span></p>
<p align=left><span>扇区号：</span><span>(11 1111) 2&nbsp;=&nbsp;(63) 10.</span></p>
<p align=left><span>柱面号：</span><span>(11 1111 1111) 2&nbsp;=&nbsp;(1023) 10</span></p>
<p align=left><span>但这是不准确的，因为当柱面号的真实值超过</span><span>1023</span><span>时，表示柱面号的</span><span>10</span><span>位也依然是</span><span>1023</span><span>。</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>5. (7E 04 7D 00):</span></p>
<p align=left><span>反向，</span><span>(00 7D 04 7E) 16&nbsp;=&nbsp;(8193150) 10. </span><span>表示扩展分区的起始扇区号为</span><span>8193150</span><span>，即</span><span>(510 </span><span>柱面，</span><span>0</span><span>磁头，</span><span>1</span><span>扇区</span><span>)</span><span>。这是真实准确的，</span></p>
<p align=left><span>我一般都用这一项来定位分区起点。</span></p>
<p align=left><span>6. (1F 2C B4 00):</span></p>
<p align=left><span>反向</span><span>, (00 B4 2C 1F) 16&nbsp;=&nbsp;(11807775) 10. </span><span>表示扩展分区共有</span><span>11807775</span><span>个扇区。通过上面得到的起点和分区的大小，</span></p>
<p align=left><span>可以推导出扩展分区的结束位置：</span><span>8193150 + 11807775 = 20000925</span><span>号扇区，即（</span><span>1244 </span><span>柱面，</span><span>254</span><span>磁头，</span><span>63</span><span>扇区）。</span></p>
<p align=left><span>二．查找</span><span>D</span><span>盘分区表</span><span> </span><span>　根据上面的信息，第二个分区表，也即</span><span>D</span><span>盘分区表在（</span><span>510</span><span>柱面，</span><span>0</span><span>磁头，</span><span>1</span><span>扇区）处。读取该扇区，得到分区表如下：</span><span> </span></p>
<p align=left><span>[00 01 41 FE 0B FE FF 7B 3F 00 00 00 BF A3 5D 00 ]</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></p>
<p align=left><span>&nbsp;[00 00 C1 7C 05 FE FF FF FE A3 5D 00 21 88 56 00 ]</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>&nbsp;[00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ]</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>&nbsp;[00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ]</span></p>
<p align=left><span>第一项：</span></p>
<p align=left><span>（</span><span>00</span><span>）（</span><span>01 41 FE</span><span>）（</span><span>0B</span><span>）（</span><span>FE FF 7B</span><span>）（</span><span>3F 00 00 00 </span><span>）（</span><span>BF A3 5D 00</span><span>）</span></p>
<p align=left><span>&nbsp;</span><span>描述的是</span><span>D</span><span>盘的情况。</span></p>
<p align=left><span>1.</span><span>（</span><span>00</span><span>）：表示</span><span>D</span><span>盘不是活动分区。</span></p>
<p align=left><span>2.</span><span>（</span><span>01 41 FE</span><span>）：</span></p>
<p align=left><span>&nbsp;(01) 16&nbsp;=&nbsp;(1) 10&nbsp;(41) 16&nbsp;=&nbsp;(0100 0001) 2&nbsp;(FE) 16&nbsp;=&nbsp;(1111 1110) 2.</span></p>
<p align=left><span>磁头号：</span><span>(1) 10</span><span>；</span></p>
<p align=left><span>扇区号：</span><span>(00 0001) 2&nbsp;=&nbsp;(1) 10.</span></p>
<p align=left><span>柱面号：</span><span>(01 1111 1110) 2&nbsp;=&nbsp;(510) 10;</span></p>
<p align=left><span>故</span><span>D</span><span>盘开始扇区为（</span><span>510</span><span>柱面，</span><span>1</span><span>磁头，</span><span>1</span><span>扇区）。</span></p>
<p align=left><span>3.</span><span>（</span><span>0B</span><span>）：表示</span><span>D</span><span>盘的文件系统为</span><span>FAT32</span><span>。</span></p>
<p align=left><span>4</span><span>．（</span><span>FE FF 7B</span><span>）：</span></p>
<p align=left><span>(FE) 16&nbsp;=&nbsp;(254) 10 </span><span>。</span><span> (FF) 16&nbsp;=&nbsp;(1111 1111) 2&nbsp;(7B) 16&nbsp;=&nbsp;(0111 1011) 2.</span></p>
<p align=left><span>磁头号：</span><span>(254) 10</span><span>；</span></p>
<p align=left><span>扇区号：</span><span>(11 1111) 2&nbsp;=&nbsp;(63) 10.</span></p>
<p align=left><span>柱面号：</span><span>(11 0111 1011) 2&nbsp;=&nbsp;(891) 10</span></p>
<p align=left><span>故</span><span>D</span><span>盘结束扇区为（</span><span>891</span><span>柱面，</span><span>254</span><span>磁头，</span><span>63</span><span>扇区）。</span></p>
<p align=left><span>5.</span><span>（</span><span>3F 00 00 00</span><span>）：</span></p>
<p align=left><span>反向，</span><span>(00 00 00 3F)16&nbsp;=&nbsp;(63)10,</span><span>为</span><span>D</span><span>盘起始逻辑扇区号（</span><span>510</span><span>柱面，</span><span>1</span><span>磁头，</span><span>1</span><span>扇区）与扩展分区起始逻辑扇区号</span></p>
<p align=left><span>（</span><span>510</span><span>柱面，</span><span>0</span><span>磁头，</span><span>1</span><span>扇区）之差。表示</span><span>D</span><span>盘前面已有</span><span>63</span><span>个扇区，这</span><span>63</span><span>个扇区为系统隐藏扇区。</span></p>
<p align=left><span>6. (BF A3 5D 00)</span><span>：</span></p>
<p align=left><span>反向，</span><span>(00 5D A3 BF) 16&nbsp;=&nbsp;(6136767) 10</span><span>。表明</span><span>D</span><span>盘有</span><span>6136767</span><span>个扇区。</span></p>
<p align=left><span>通过上面得到的起点和分区的大小，可以推导出</span><span>D</span><span>盘的结束位置：</span><span>8193150 + 63 + 6136767 = 14329980</span><span>号扇区。</span></p>
<p align=left><span>即（</span><span>891</span><span>柱面，</span><span>254</span><span>磁头，</span><span>63</span><span>扇区）。与上面的正好吻合。</span></p>
<p align=left><span>第二项：</span></p>
<p align=left><span>(00)</span><span>（</span><span>00 C1 7C</span><span>）（</span><span>05</span><span>）（</span><span>FE FF FF</span><span>）（</span><span>FE A3 5D 00</span><span>）（</span><span>21 88 56 00</span><span>）</span></p>
<p align=left><span>描述的是</span><span>E</span><span>盘的情况。</span></p>
<p align=left><span>1. (00)</span><span>：</span><span> </span><span>表示</span><span>E</span><span>盘不是活动分区。</span></p>
<p align=left><span>2. (00 C1 7C)</span><span>：</span></p>
<p align=left><span>(00) 16&nbsp;=&nbsp;(0) 10&nbsp;(C1) 16&nbsp;=&nbsp;(1100 0001) 2&nbsp;(7C) 16&nbsp;=&nbsp;(0111 1100) 2</span></p>
<p align=left><span>磁头号：</span><span>(0) 10</span></p>
<p align=left><span>扇区号：</span><span>(00 0001) 2&nbsp;=&nbsp;(1) 10</span></p>
<p align=left><span>柱面号：</span><span>(11 0111 1100) 2&nbsp;=&nbsp;(892) 10</span></p>
<p align=left><span>所以</span><span>E</span><span>盘的起始扇区为（</span><span>892</span><span>柱面，</span><span>0</span><span>磁头，</span><span>1</span><span>扇区）。</span></p>
<p align=left><span>3. (05): </span><span>表示</span><span>E</span><span>盘的在扩展分区里面。</span></p>
<p align=left><span>4</span><span>．</span><span>(FE FF FF)</span><span>：</span></p>
<p align=left><span>(FE) 16&nbsp;=&nbsp;(254) 10&nbsp;(FF) 16&nbsp;=&nbsp;(1111 1111) 2&nbsp;(FF) 16&nbsp;=&nbsp;(1111 1111) 2</span></p>
<p align=left><span>磁头号：</span><span>(254) 10</span></p>
<p align=left><span>扇区号：</span><span>(11 1111) 2&nbsp;=&nbsp;(63) 10</span></p>
<p align=left><span>柱面号：</span><span>(11 1111 1111) 2&nbsp;=&nbsp;(1023) 10</span></p>
<p align=left><span>但这是不准确的，原因同上。</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>5</span><span>．</span><span>(FE A3 5D 00):</span></p>
<p align=left><span>&nbsp;</span><span>反向，</span><span>(00 5D A3 FE) 16&nbsp;=&nbsp;(6136830) 10. </span><span>这一项非常重要，它定位了</span><span>E</span><span>盘分区表所在扇区。其值为</span><span>E</span><span>盘分区表所在扇区号</span></p>
<p align=left><span>&nbsp;</span><span>与扩展分区起始扇区号之差。所以，</span><span>E</span><span>盘分区表所在扇区号为：</span></p>
<p align=left><span>8193150 + 6136830 = 14329980</span><span>。即（</span><span>892</span><span>柱面，</span><span>0</span><span>磁头，</span><span>1</span><span>扇区）。</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>6</span><span>．</span><span>(21 88 56 00):</span></p>
<p align=left><span>反向，</span><span>(00 56 88 21) 16&nbsp;=&nbsp;(5670945) 10.</span><span>表示</span><span>E</span><span>盘共有</span><span>11807775</span><span>个扇区。通过上面得到的起点和分区的大小，可以推导出</span><span>E</span></p>
<p align=left><span>盘的结束位置：</span><span>14329980 + 5670945 = 20000925</span><span>号扇区，即（</span><span>1244 </span><span>柱面，</span><span>254</span><span>磁头，</span><span>63</span><span>扇区）。</span></p>
<p align=left><span>三．查找</span><span>E</span><span>盘分区表</span><span> </span><span>根据上面的信息，第三个分区表，也即</span><span>E</span><span>盘分区表在（</span><span>892</span><span>柱面，</span><span>0</span><span>磁头，</span><span>1</span><span>扇区）处。读取该扇区，得到分区表如下：</span><span> </span></p>
<p align=left><span>[00 01 C1 7C 0B FE FF FF 3F 00 00 00 E2 87 56 00]</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>[ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ]</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>[00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ]</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>[00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ]</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>该分区表第二项全为</span><span>0</span><span>，说明没有下一个分区表了。该分区表就是分区表链的最后一个节点。</span></p>
<p align=left><span>第一项：</span></p>
<p align=left><span>（</span><span>00</span><span>）（</span><span>01 C1 7C</span><span>）（</span><span>0B</span><span>）（</span><span>FE FF FF</span><span>）（</span><span>3F 00 00 00 </span><span>）（</span><span>E2 87 56 00</span><span>）</span></p>
<p align=left><span>该项与</span><span>D</span><span>盘分区表的第二项描述的都是</span><span>E</span><span>盘的情况，但它们在某些细节上又有所区别。</span></p>
<p align=left><span>1.</span><span>（</span><span>00</span><span>）：表示</span><span>E</span><span>盘不是活动分区。</span></p>
<p align=left><span>2.</span><span>（</span><span>01 C1 7C</span><span>）：</span></p>
<p align=left><span>&nbsp;(01) 16&nbsp;=&nbsp;(1) 10&nbsp;(C1) 16&nbsp;=&nbsp;(1100 0001) 2&nbsp;(7C) 16&nbsp;=&nbsp;(0111 1100) 2.</span></p>
<p align=left><span>磁头号：</span><span>(1) 10</span></p>
<p align=left><span>扇区号：</span><span>(00 0001) 2&nbsp;=&nbsp;(1) 10</span></p>
<p align=left><span>柱面号：</span><span>(11 0111 1100) 2&nbsp;=&nbsp;(892) 10</span></p>
<p align=left><span>故</span><span>E</span><span>盘起始扇区为（</span><span>892</span><span>柱面，</span><span>1</span><span>磁头，</span><span>1</span><span>扇区）。</span></p>
<p align=left><span>3.</span><span>（</span><span>0B</span><span>）：表示</span><span>E</span><span>盘的文件系统为</span><span>FAT32</span><span>。</span></p>
<p align=left><span>4</span><span>．（</span><span>FE FF FF</span><span>）：</span></p>
<p align=left><span>(FE) 16&nbsp;=&nbsp;(254) 10 </span><span>。</span><span> (FF) 16&nbsp;=&nbsp;(1111 1111) 2&nbsp;(FF) 16&nbsp;=&nbsp;(1111 1111) 2.</span></p>
<p align=left><span>磁头号：</span><span>(254) 10</span><span>；</span></p>
<p align=left><span>扇区号：</span><span>(11 1111) 2&nbsp;=&nbsp;(63) 10.</span></p>
<p align=left><span>柱面号：</span><span>(11 1111 1111) 2&nbsp;=&nbsp;(1023) 10</span></p>
<p align=left><span>但这是不准确的，原因同上。</span></p>
<p align=left><span>5.</span><span>（</span><span>3F 00 00 00</span><span>）：</span></p>
<p align=left><span>反向，</span><span>(00 00 00 3F) 16&nbsp;=&nbsp;(63) 10.</span><span>这一项与</span><span>D</span><span>盘分区表相应项有所不同</span><span>.</span><span>为</span><span>E</span><span>盘起始逻辑</span></p>
<p align=left><span>扇区号（</span><span>892</span><span>柱面，</span><span>1</span><span>磁头，</span><span>1</span><span>扇区）与（</span><span>892</span><span>柱面，</span><span>0</span><span>磁头，</span><span>1</span><span>扇区）之差。表示</span><span>E</span><span>盘前面已有</span><span>63</span><span>个扇区</span><span>, </span><span>这</span><span>63</span><span>个扇区为系统隐藏扇区。</span></p>
<p align=left><span>操作系统无法对这些扇区进行读写</span><span>,</span><span>所以可以把自己的秘密信息写在这里</span><span>.</span></p>
<p align=left><span>6. (E2 87 56 00): </span></p>
<p align=left><span>反向，</span><span>(00 56 87 E2) 16&nbsp;=&nbsp;(5670882) 10</span><span>。表明</span><span>E</span><span>盘有</span><span>5670882</span><span>个扇区。而</span><span>D</span><span>盘分区表相应项为</span><span>5670945. 5670945 - 5670882 = 63.</span></p>
<p align=left><span>正好等于</span><span>63</span><span>个隐藏扇区</span><span>.</span><span>这是因为</span><span>D</span><span>盘分区表描述的是</span><span>(892</span><span>柱面</span><span>,0</span><span>磁头，</span><span>1</span><span>扇区</span><span>) </span><span>到</span><span> (1244 </span><span>柱面，</span><span>254</span><span>磁头，</span><span>63</span><span>扇区</span><span>) </span><span>之间的扇区数。</span></p>
<p align=left><span>而</span><span>E</span><span>盘分区表描述的是</span><span>(892</span><span>柱面</span><span>, 1</span><span>磁头</span><span>,1</span><span>扇区</span><span>) </span><span>到</span><span> (1244 </span><span>柱面，</span><span>254</span><span>磁头，</span><span>63</span><span>扇区</span><span>) </span><span>之间的扇区数。</span></p>
<p><strong><span>四</span></strong><strong><span>.</span></strong><strong><span>结束语</span></strong><span> <br>&nbsp;&nbsp;&nbsp; </span><span>至此</span><span>,</span><span>我们已经打通了整个分区表链</span><span>.</span><span>以后在某个链节点数据受损时</span><span>,</span><span>也可以根据上下节点的信息而手工定位并修复之。</span><span> <br></span><span>修复工具可采用可读写磁盘的</span><span>Winhex. <br><br>上文是两们研的成果，在戴士剑的《数据恢复》一书也有介绍，关于C的算法实现对引导记录的读写在后面自己实践了再贴出来。</span></p>
<img src ="http://www.cppblog.com/snowhill/aggbug/36202.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/snowhill/" target="_blank">snowhill</a> 2007-11-09 13:29 <a href="http://www.cppblog.com/snowhill/archive/2007/11/09/36202.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>KMP算法</title><link>http://www.cppblog.com/snowhill/archive/2007/01/07/17384.html</link><dc:creator>snowhill</dc:creator><author>snowhill</author><pubDate>Sun, 07 Jan 2007 03:40:00 GMT</pubDate><guid>http://www.cppblog.com/snowhill/archive/2007/01/07/17384.html</guid><wfw:comment>http://www.cppblog.com/snowhill/comments/17384.html</wfw:comment><comments>http://www.cppblog.com/snowhill/archive/2007/01/07/17384.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/snowhill/comments/commentRss/17384.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/snowhill/services/trackbacks/17384.html</trackback:ping><description><![CDATA[
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">/*</span>
				<span style="COLOR: #008000"> data:2007 -1 - 7 by:snowhill<br /> char *s="abcdefhighcbcccfghiabcdefghikl";<br /> char *T="cbcbc"; next[]的值应为:    -1,0,0,1,2<br /> 如果char *T="cbccc";next[]的值应为: -1,0,0,1,1<br /> next[]的求法相当于T自身的一个模式匹配<br /><br /> 在KMP_Find()中 如果J的值大于T的长度则查找成功<br /> </span>
				<span style="COLOR: #008000">*/</span>
				<span style="COLOR: #000000">
						<br />#include </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">iostream.h</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> length(</span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">s)<br />{<br /> </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> i</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">;<br /> </span>
				<span style="COLOR: #0000ff">while</span>
				<span style="COLOR: #000000">(s[i]</span>
				<span style="COLOR: #000000">!=</span>
				<span style="COLOR: #000000">NULL)<br /> i</span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000">;<br /> </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> i;<br />}<br /><br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> get_next(</span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">T,</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">next)<br />{<br />   </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000">  i </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">, j </span>
				<span style="COLOR: #000000">=-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">; <br />   next[</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">] </span>
				<span style="COLOR: #000000">=-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">;<br />     </span>
				<span style="COLOR: #0000ff">while</span>
				<span style="COLOR: #000000"> (i</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">length(T))<br />     {<br />          </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(j</span>
				<span style="COLOR: #000000">==-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">||</span>
				<span style="COLOR: #000000">T[i]</span>
				<span style="COLOR: #000000">==</span>
				<span style="COLOR: #000000">T[j]) <br />            {             <br />              </span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000"> i;<br />              </span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000"> j; <br />              cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">i=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">i</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">j=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">j</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">endl;<br />              next[i]</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">j;              <br />             }<br />            </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000"> j</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">next[j];<br />          }</span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000">end while    </span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">  </span>
				<span style="COLOR: #0000ff">for</span>
				<span style="COLOR: #000000">(</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> l</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">;l</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">length(T);l</span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000">)<br />     cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">next[l]</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">\t</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">;<br />     <br />cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">endl;<br />}<br /></span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> KMP算法</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> KMP_Find(</span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">s, </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">T)<br />{<br />          </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> i</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">, j</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">,k</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">length(s);<br />          cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">k=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">k</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">endl;<br />          </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">next</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #0000ff">new</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000">[k];<br />          get_next(T,next);<br />          </span>
				<span style="COLOR: #0000ff">while</span>
				<span style="COLOR: #000000"> (i</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">k)<br />          {<br />              </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000"> (j</span>
				<span style="COLOR: #000000">=-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">||</span>
				<span style="COLOR: #000000">s[i] </span>
				<span style="COLOR: #000000">==</span>
				<span style="COLOR: #000000"> T[j]){ </span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000">i; </span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000">j; }<br />              </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000"> j </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> next[j];<br />          }<br />          </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000"> (j</span>
				<span style="COLOR: #000000">&gt;=</span>
				<span style="COLOR: #000000">length(T))  cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">查找完毕!未找到</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">endl;<br />          </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000">  cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">查找成功!</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">;<br />          <br />}<br /></span>
				<span style="COLOR: #008000">/*</span>
				<span style="COLOR: #008000"> 原始查找算法 </span>
				<span style="COLOR: #008000">*/</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> find(</span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">s,</span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">T)<br />{<br /> </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> i</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">,j</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">,k</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">length(s);<br /> </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(j</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">length(T)</span>
				<span style="COLOR: #000000">&amp;&amp;</span>
				<span style="COLOR: #000000">i</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">k)<br />  {<br />  </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(s[i]</span>
				<span style="COLOR: #000000">==</span>
				<span style="COLOR: #000000">T[j])<br />   {<br />   j</span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000">;<br />   i</span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000">;<br />   } <br />  </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000"> {i</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">i</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">j</span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">;j</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">;} <br />  }<br />  </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(j</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">length(T)</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">)<br />  cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">find is sucess!</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">endl;<br />  </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000"> <br />  cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">error!</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">endl;<br />}<br /> </span>
				<span style="COLOR: #008000">/*</span>
				<span style="COLOR: #008000"> 测试函数 </span>
				<span style="COLOR: #008000">*/</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> main()<br />{<br /> </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">s</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">abcdefhighcbcccfghiabcdefghikl</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">;<br /> </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">T</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">cbcbc</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">;<br /> find(s,T);<br /> KMP_Find(s,T);<br />    <br />}<br /></span>
		</div>
<img src ="http://www.cppblog.com/snowhill/aggbug/17384.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/snowhill/" target="_blank">snowhill</a> 2007-01-07 11:40 <a href="http://www.cppblog.com/snowhill/archive/2007/01/07/17384.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>整数溢出问题</title><link>http://www.cppblog.com/snowhill/archive/2006/12/31/17103.html</link><dc:creator>snowhill</dc:creator><author>snowhill</author><pubDate>Sun, 31 Dec 2006 12:24:00 GMT</pubDate><guid>http://www.cppblog.com/snowhill/archive/2006/12/31/17103.html</guid><wfw:comment>http://www.cppblog.com/snowhill/comments/17103.html</wfw:comment><comments>http://www.cppblog.com/snowhill/archive/2006/12/31/17103.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/snowhill/comments/commentRss/17103.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/snowhill/services/trackbacks/17103.html</trackback:ping><description><![CDATA[
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">#include </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">iostream.h</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> main()<br />{<br />    </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> n</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">,sum</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">;<br />    cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">int inquire </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #0000ff">sizeof</span>
				<span style="COLOR: #000000">(</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000">)</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000"> bytes</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">endl;<br /><br /></span>
				<span style="COLOR: #0000ff">while</span>
				<span style="COLOR: #000000">(sum</span>
				<span style="COLOR: #000000">&lt;=</span>
				<span style="COLOR: #000000">4294967295</span>
				<span style="COLOR: #000000">) {sum</span>
				<span style="COLOR: #000000">+=</span>
				<span style="COLOR: #000000">n; n</span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000">;}<br /><br />cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">n=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">n</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">;<br /><br />    <br />}</span>
		</div>上面程序是一个无限循环（在VC6.0中)。如果将4294967295改为4294967294则行。<img src ="http://www.cppblog.com/snowhill/aggbug/17103.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/snowhill/" target="_blank">snowhill</a> 2006-12-31 20:24 <a href="http://www.cppblog.com/snowhill/archive/2006/12/31/17103.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>