简体   繁体   中英

How to pull specific data from a Base64String?

This is directly related to how to generate a unique token which expires after 24 hours?

What I am attempting to do is embed the following:

  1. A Page Number (0 through 6)
  2. Current Date/Time Stamp in UTC Format
  3. and A Unique GUID

The code I have so far is this:

private string GenerateToken(Int32 pageNumber)
{
    byte[] currentTimeStamp = BitConverter.GetBytes(DateTime.UtcNow.ToBinary());
    byte[] key = Guid.NewGuid().ToByteArray();
    byte[] newPageNumber = BitConverter.GetBytes(pageNumber);
    string token = Convert.ToBase64String(newPageNumber.Concat(currentTimeStamp).Concat(key).ToArray());
    return token;
}

private tokenClass TokenAuthenticates(string token)
{
    byte[] data = Convert.FromBase64String(token);

    tokenClass _token = new tokenClass()
    {
        PageNumber = 0,
        TokenDateTimeStamp = DateTime.FromBinary(BitConverter.ToInt64(data, 1)),
        TokenKey = new Guid(),
        Validates = (DateTime.FromBinary(BitConverter.ToInt64(data, 1)) < DateTime.UtcNow.AddHours(-2))
    };

    return _token;
}

The page and Guid parameters in the decoder are not yet figured out yet so they are basically dummies.

What do I need to do to make this work?

Generate your token like this:

private static string GenerateToken(Int32 pageNumber)
{
    byte[] currentTimeStamp = BitConverter.GetBytes(DateTime.UtcNow.ToBinary());
    var keyGuid = Guid.NewGuid();
    byte[] key = keyGuid.ToByteArray();
    byte[] newPageNumber = BitConverter.GetBytes(pageNumber);

    // date plus page number plus key
    string token = Convert.ToBase64String(currentTimeStamp.Concat(newPageNumber).Concat(key).ToArray());
    return token;
}

Read the token like this (in your TokenAuthenticates method):

byte[] data = Convert.FromBase64String(token);

// It will take eight bytes starting at index 0
DateTime when = DateTime.FromBinary(BitConverter.ToInt64(data, 0)); 

// 8 first bytes was taken by date so lets skip 8 and then take 4 since page number is an integer and takes 4 bytes
int pageNumber = BitConverter.ToInt32(data.Skip(8).Take(4).ToArray(), 0);

// 8 bytes for date + 4 bytes for page number so we skip 12 and then take 16 for Guid
// Guid can be generated directly from the bytes
Guid key = new Guid(data.Skip(12).Take(16).ToArray());

Here is a way so you do not have to hardcode the numbers or determine the size. Use the sizeof operator to do the determination for you:

int pageNumber = BitConverter.ToInt32(data.Skip(sizeof(long))
                     .Take(sizeof(int)).ToArray(), 0);

// Skip date and pageNumber, the rest is Guid
Guid key = new Guid(data.Skip(sizeof(long) + sizeof(int)).ToArray());

I would call the method AuthenticateToken since it is an action verb and sounds more readable and clear. You can perform your further validation after you have read the token. You may want to consider encrypting the token too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM