【问题标题】:How to pull specific data from a Base64String?如何从 Base64String 中提取特定数据?
【发布时间】:2017-05-06 10:14:33
【问题描述】:

这与how to generate a unique token which expires after 24 hours?直接相关

我试图做的是嵌入以下内容:

  1. 页码(0 到 6)
  2. UTC 格式的当前日期/时间戳
  3. 和唯一的 GUID

我目前的代码是这样的:

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

decoder中的page和Guid参数还没搞清楚,基本都是假的。

我需要做什么才能完成这项工作?

【问题讨论】:

  • 什么不起作用?
  • 首先...我需要能够从 Base64String 中提取页码,但我不知道该怎么做。此外,guid 的日期显示为 1594 而不是 2016,与页码相同,验证仅取决于有效日期
  • 我实际上没有...我正在尝试修改引用的示例 SO 页面,不幸的是我完全没有运气。

标签: c#


【解决方案1】:

像这样生成你的令牌:

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

像这样读取令牌(在您的 TokenAuthenticates 方法中):

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());

这是一种无需对数字进行硬编码或确定大小的方法。使用sizeof 运算符为您做决定:

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());

我会调用方法AuthenticateToken,因为它是一个动作动词,听起来更易读、更清晰。阅读令牌后,您可以执行进一步的验证。您也可以考虑加密令牌。

【讨论】:

  • 是的,这就是为什么我将 cmets 放入代码中以避免混淆。
猜你喜欢
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-18
  • 1970-01-01
  • 1970-01-01
  • 2017-09-12
  • 1970-01-01
相关资源
最近更新 更多