C#生成比较短的Token字符串

 更新时间:2022年06月22日 09:52:15   作者:天方  
这篇文章介绍了C#生成Token字符串的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

有的时候,我们需要生成一些Token作为标识:如认证后的标识符,资源的提取码等。一个比较常见的算法是生成一个GUID来作为Token,由于GUID的随机性和唯一性特点,作为Token是一个非常可靠的选择。

GUID是一个128bit的数组,为了方便携带,往往需要把它表述为字符串的形式。一般把它表述为如下形式:{79FAF822-7194-4FE3-8C4F-1D99BE71BC9C}。这样有一个弊病:太长了,那么我们如何把它弄短点呢?

去掉不必要的修饰符

首先可以通过去掉无意义的括号和减号来较少长度:

var token = guid.ToString("N");

这样字符串就成为:79faf82271944fe38c4f1d99be71bc9c。感觉还是蛮长的。

使用Base64编码来表示

前面的表示方法中,是使用的16机制来表示的,如果使用Base64编码的话,则可以进一步压缩字符串

var token = Convert.ToBase64String(guid.ToByteArray()).TrimEnd('=');

这样字符串就成为:Ivj6eZRx40+MTx2ZvnG8nA。看起来稍微好一点了。

换一种Token生成方式

在使用Base64方式的编码后,Token字符串还是有20多位,有的时候还是嫌它长了。由于GUID本身就有128bit,在要求有良好的可读性的前提下,很难进一步改进了。那我们如何产生更短的字符串呢?还有一种方式就是较少Token的长度,不用GUID,而采用一定长度的随机数,例如64bit,再用Base64编码表示:

var rnd = new Random();
var tokenData = new byte[8];
rnd.NextBytes(tokenData);
var token = Convert.ToBase64String(tokenData).TrimEnd('=');

由于这里只用了64bit,此时得到的字符串为Onh0h95n7nw的形式,长度要短一半。这样就方便携带多了。但是这种方式是没有唯一性保证的。不过用来作为身份认证的方式还是可以的(如网盘的提取码)。

更进一步

前面的算法中,长度和随机性倒是有了,但是没有唯一性。对于需要唯一性的场景,则需要改写一下token的生成算法了,我在这里给一个简单的示例:

    class Token
    {
        static Random rnd = new Random();
        static int seed = 0;

        public static string Create()
        {
            var rndData = new byte[4];
            rnd.NextBytes(rndData);

            var seedValue = Interlocked.Add(ref seed, 1);
            var seedData = BitConverter.GetBytes(seedValue);

            var tokenData = rndData.Concat(seedData).OrderBy(_ => rnd.Next());
            return Convert.ToBase64String(tokenData.ToArray()).TrimEnd('=');
        }
    }

这里我的算法非常简单:

  • token由两部分组成,32位的随机数+32位的序列
  • 由序列保证唯一性,由随机数保证随机性。
  • 组合后再进行一次shuffle。

当然,我这个算法也有一定的局限性,如:

  • Token只能在4G范围内保证唯一
  • Token只能在上下文中保证唯一
  • Token不是完全随机的

要解决这几个问题,实现在任何时候,任何位置,任何情况下产生的Token都具有唯一性和随机性也是能做到的。但是,要知道的是,任何功能都是附有一定的代价的。这些条件往往带来的代价就是Token长度增加——GUID就是满足这一系列条件的算法。软件的世界没有银弹,我们只要在一定范围内找到能解决问题的方法即可。

到此这篇关于C#生成Token字符串的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C#通过流写入一行数据到文件的方法

    C#通过流写入一行数据到文件的方法

    这篇文章主要介绍了C#通过流写入一行数据到文件的方法,涉及C#针对文本文件读写的基本技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • winform去掉右上角关闭按钮的方法

    winform去掉右上角关闭按钮的方法

    这篇文章主要介绍了winform去掉右上角关闭按钮的方法,需要的朋友可以参考下
    2014-02-02
  • 利用C#实现在Word中更改字体颜色

    利用C#实现在Word中更改字体颜色

    在日常工作中,我们有时会需要修改字体的颜色来突出文本重点,让读者更容易抓住文章要点。在今天这篇文章中,我将为大家介绍如何以编程方式,在Word更改字体颜色,感兴趣的可以了解一下
    2023-02-02
  • C#进行文件读写、创建、复制、移动、删除的方法

    C#进行文件读写、创建、复制、移动、删除的方法

    这篇文章主要介绍了C#进行文件读写、创建、复制、移动、删除的方法,涉及C#针对文件操作的常用技巧,非常具有实用价值,需要的朋友可以参考下
    2015-03-03
  • C++中#include头文件的示例详解

    C++中#include头文件的示例详解

    在C++中,所有的文件操作,都是以流(stream)的方式进行的,fstream也就是文件流file stream。这篇文章主要介绍了C++中#include头文件,需要的朋友可以参考下
    2020-02-02
  • C#编程获取客户端计算机硬件及系统信息功能示例

    C#编程获取客户端计算机硬件及系统信息功能示例

    这篇文章主要介绍了C#编程获取客户端计算机硬件及系统信息功能,可实现针对客户端系统CPU、硬盘、主板等硬件信息及客户端操作系统、IP、MAC等信息的操作技巧,需要的朋友可以参考下
    2017-01-01
  • C# SortedList排序列表的实现

    C# SortedList排序列表的实现

    本文主要介绍了C# SortedList排序列表的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • C#从DataTable获取数据的方法

    C#从DataTable获取数据的方法

    这篇文章主要介绍了C#从DataTable获取数据的方法,涉及C#操作DataTable的相关技巧,需要的朋友可以参考下
    2015-06-06
  • C# JavaScriptSerializer序列化时的时间处理详解

    C# JavaScriptSerializer序列化时的时间处理详解

    这篇文章主要为大家详细介绍了C# JavaScriptSerializer序列化时的时间处理详解,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • C#同步网络时间的方法实例详解

    C#同步网络时间的方法实例详解

    这篇文章主要介绍了C#同步网络时间的方法,以实例形式较为详细的分析了C#获取网络时间与同步本机系统时间的相关技巧,非常具有实用价值,需要的朋友可以参考下
    2015-05-05

最新评论