locked
How to interprete Thread-Index header RRS feed

  • Question

  • There is an MSDN entry about Thread-Index value but it differs from reality. If you implement parsed based on information on MSDN it will not work. I managed to write a class that will parse the Thread-Index header like this:

    public class OutlookThreadIndex
    {
       
    public DateTime Date { get; private set; }
       
    public Guid Id { get; private set; }
       
    public string Raw { get; private set; }

       
    public bool IsValid
       
    {
           
    get { return Date != default(DateTime) && Id != default(Guid); }
       
    }

       
    public OutlookThreadIndex(string threadIndexValue)
       
    {
           
    Raw = threadIndexValue;

           
    var bytes = Convert.FromBase64String(threadIndexValue);

           
    // thread index length should be 22 plus extra 5 bytes per reply
           
    if (bytes.Length < 22 || (bytes.Length - 22) % 5 != 0)
               
    return;

           
    Id = new Guid(bytes.Skip(6).Take(16).ToArray());

           
    var headerTicks = bytes
               
    .Take(6)
               
    .Select(b => (long) b)
               
    .Aggregate((l1, l2) => (l1 << 8) + l2)
               
    << 16;

           
    Date = new DateTime(headerTicks, DateTimeKind.Utc).AddYears(1600);

           
    var childBlockCount = (bytes.Length - 22) / 5;

           
    for (var i = 0; i < childBlockCount; i++)
           
    {
               
    var childTicks = bytes
                   
    .Skip(22 + i*5).Take(4)
                   
    .Select(b => (long) b)
                   
    .Aggregate((l1, l2) => (l1 << 8) + l2)
                   
    << 18;

                childTicks
    &= ~((long) 1 << 50);
               
    Date = Date.AddTicks(childTicks);
           
    }
       
    }

       
    public override string ToString()
       
    {
           
    return string.Format("Id: {0}, Date: {1}", Id, Date.ToLocalTime());
       
    }
    }

    I have tested this against a series of email and found out that a lot of them are parsed incorrectly. Here is an example:

    • Thread-Index: AQLNahwAkMF4P9Bl8t7dPDytf5aNnA==
    • Parsed Id: 3f78c190-65d0-def2-dd3c-3cad7f968d9c
    • Parsed Date: 1831-11-05 00:06:01

    And here is another one:

    • Thread-Index: Ac6ocXoGclflrAlgQg2VFL1JFq6hyg==
    • Parsed Date: 2013-09-03 08:47:37
    • Parsed Id: ace55772-6009-0d42-9514-bd4916aea1ca

    The first Thread-Index is invalid (see year 1831). The second one is ok. What is interesing is that both Thread-Indexes are from the same mail message but the first one is from senders Sent folder and the other one is from recipients Inbox folder. I'm using Outlook 2013. Also interesting fact, all indexes that seem invalid have date around year 1800. Can I receive any information about how Thread-Index value is constructed?

    Tuesday, September 3, 2013 8:21 PM