# NTFS中Data Run换算成LCN算法

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).

        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;
}