有的时候,我们需要生成一些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('=');
        }
    }

这里我的算法非常简单:

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

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

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

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

生成比较短的Token字符串的更多相关文章

  1. 生成Token字符串

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

  2. (C#)生成指定长度的随机字符串的通用方法

    .NET(C#)生成指定长度的随机字符串的通用方法,此方法可以指定字符串的长度,是否包含数字,是否包含符号,是否包含小写字母,是否包含大写字母等, 源码: #region 生成指定长度的随机字符串 / ...

  3. js随机生成字母数字组合的字符串 随机动画数字

    效果描述: 附件中只有一个index.html文件有效 其中包含css以及html两部分内容 纯js生成的几个随机数字 每次都不重复,点击按钮后再次切换 使用方法: 1.将css样式引入到你的网页中 ...

  4. Python 生成 JWT(json web token) 及 解析方式

    一.关于 jwt 的原理及概念可以自行在网络上搜索了解一下,这里推荐一篇写的比较好的博客 深入了解Json Web Token之概念篇 另附 JWT 的官方文档: https://jwt.io/int ...

  5. 去掉C#中Guid.NewGuid().ToString()自动生成的短横线

    别人设计的ID类型为varchar(32),使用Guid.NewGuid().ToString()自动生成ID值,本来大小32位妥妥的.可C#在生成的ID值中自动生成了几根小横杠,你说是不是讨嫌. 岂 ...

  6. CreateJS结合Falsh工具生成Canvas动画(加密字符串的由来)

    CreateJS是一款制作Canvas动画的工具. 官网如下: http://www.createjs.com/ http://www.createjs.cc/ 使用CreateJS时最大的疑问就是J ...

  7. Java生成固定长度的随机字符串(以大小写字母和数字)

    package org.jimmy.autosearch2019.test; import java.util.ArrayList; import java.util.Random; /** * @a ...

  8. python中生成JWK(json web token)

    #需要安装pyjwt import jwt import time # 使用 sanic 作为restful api 框架 def create_token(request): grant_type ...

  9. Java 生成六位短信验证码

    在<Java 生成三位随机数>中,简要介绍了使用Java生成三位随机数的方法,前几天在工作中遇到生成6位短信验证码的需求,验证码由6位随机数字构成,不包含字母.6位随机数通常用作短信验证码 ...

随机推荐

  1. JS判断单、多张图片加载完成

    转:http://www.daqianduan.com/6419.html 试想,如果模板中有图片,此时如何判断图片是否加载完成? 在此之前来了解一下jquery的ready与window.onloa ...

  2. Activiti学习记录(三)

    1.流程变量 1.1 流程图 流程变量在整个工作流中扮演很重要的作用.例如:请假流程中有请假天数.请假原因等一些参数都为流程变量的范围.流程变量的作用域范围是只对应一个流程实例.也就是说各个流程实例的 ...

  3. Linux yum安装

    一.安装Apache软件步骤:1.安装 yum install httpd 2.启动,关闭 重启等命令systemctl start httpd.service(启动)systemctl restar ...

  4. vue:vue router学习小结

    序:本篇内容主要侧重对前端路由的理解,以vue的官方路由作为载体,进行一个简单介绍. 一.路由历史: 最早开始的时候,项目开发使用的是SSR,即服务端渲染.这个时候刷新页面,服务器返回的是全部的htm ...

  5. Sum All Odd Fibonacci Numbers-freecodecamp算法题目

    Sum All Odd Fibonacci Numbers 1.要求 给一个正整数num,返回小于或等于num的斐波纳契奇数之和. 斐波纳契数列中的前几个数字是 1.1.2.3.5 和 8,随后的每一 ...

  6. Visual Studio 2017 初次体验

    在初次体验中遇到以下问题以及技巧 1. 在出现红色波浪线时为出现错误语法,将鼠标移动到相应位置可以获得相关错误信息 2.在编写代码过程中,行号上出现的小黄灯可以有提示信息 3.List 与 Array ...

  7. 项目实战14.1—ELK 企业内部日志分析系统

    本文收录在Linux运维企业架构实战系列 一.els.elk 的介绍 1.els,elk els:ElasticSearch,Logstash,Kibana,Beats elk:ElasticSear ...

  8. Python_列表、字典、字符串、集合操作

    一.list Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素.对于list的操作,我们要学会增删改查. 查 我们可以直接索引查找,也可以通过切片 ...

  9. go包的理解

    结论: import时指定的字符串,是相对于$GOPATH的目录路径,告诉了go,要去加载这个目录下所有的包文件(不包括子目录中的文件) 一个目录中所有的源文件(不包括子目录)代表了单独的一个包,这些 ...

  10. python代码notepad++不变色问题。

    原来是文档后缀名是.txt造成的,应该改成.py,疏忽了...