NTFS中Data Run换算成LCN算法


文章中用实现代码为C#。
对于该算法,我参照相关原理自己写了一个,在根目录下复制了大量文件进行测试,发现有问题,之后,参考一下两个链接:
http://blog.csdn.net/redchairman/article/details/5694027
http://www.reddragonfly.org/ntfs/concepts/data_runs.html
第一个链接里提到了一种算法,结果跟我自己写的有一样的错误。愿意是第二个链接里提到了,如下:

Example 3 - Normal, Scrambled File

Data runs:

  • 11 30 60 21 10 00 01 11 20 E0 00
  • 11 30 60 - 21 10 00 01 - 11 20 E0 - 00 (regrouped)

Run 1:

  • Header = 0x11 - 1 byte length, 1 byte offset
  • Length = 0x30
  • Offset = 0x60

Run 2:

  • Header = 0x21 - 1 byte length, 2 byte offset
  • Length = 0x10
  • Offset = 0x160 (0x100 relative to 0x60)

Run 3:

  • Header = 0x11 - 1 byte length, 1 byte offset
  • Length = 0x20
  • Offset = 0x140 (-0x20 relative to 0x160)

Run 4:

  • Header = 0x00 - the end

Summary:

  • 0x30 Clusters @ LCN 0x60
  • 0x10 Clusters @ LCN 0x160
  • 0x20 Clusters @ LCN 0x140

Therefore, Data3 is a badly fragmented file of size 0x80 clusters, with data blocks at LCNs 0x60, 0x160 and 0x140. Furthermore, the third block of data is physically located between the first and second blocks. (The third run has a negative offset, placing it before the previous run).


链接一个中的算法和我的算法都忽略了Offset为负数(negative)的情况。我将链接一种的算法进行改进,结果如下:
        public unsafe static long RunLCN(byte* pRun)
        {
            byte n1 = (byte)(*pRun & 0x0f);
            byte n2 = (byte)((*pRun >> 4) & 0x0f);

            byte lcnCheck = (n2 == 0) ? (byte)0 : (byte)(pRun[n1 + n2]);
            bool negative = false;
            if ((0x80 & lcnCheck) == 0x80) // Negative.
            {
                negative = true;
            }

            // If the highest byte is a negative value (the highest bit is 1), than we should get a negative long value respectively.
            long lcn = negative ? (long)((0xffffffffffffffff << 8) | lcnCheck) : (long)lcnCheck;

            for (int i = n1 + n2 - 1; i > n1; i--)
            {
                lcn = (lcn << 8) + pRun[i];
            }

            return lcn;
        }

经测试,成功。


你可能感兴趣的:(算法,header,测试,C#,byte,n2)