生成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就是满足这一系列条件的算法。软件的世界没有银弹,我们只要在一定范围内找到能
解决问题的方法即可。
System.Guid guid = System.Guid.NewGuid(); //Guid 类型 string strGUID = System.Guid.NewGuid().ToString(); //直接返回字符串类型
生成Token字符串的更多相关文章
- 生成比较短的Token字符串
有的时候,我们需要生成一些Token作为标识:如认证后的标识符,资源的提取码等.一个比较常见的算法是生成一个GUID来作为Token,由于GUID的随机性和唯一性特点,作为Token是一个非常可靠的选 ...
- JAVA后端生成Token(令牌),用于校验客户端,防止重复提交
转:https://blog.csdn.net/u011821334/article/details/79390980 转:https://blog.csdn.net/joshua1830/artic ...
- 国服最强JWT生成Token做登录校验讲解,看完保证你学会!
转载于:https://blog.csdn.net/u011277123/article/details/78918390 Free码农 2017-12-28 00:08:02 JWT简介 JWT(j ...
- Java生鲜电商平台-Java后端生成Token架构与设计详解
Java生鲜电商平台-Java后端生成Token架构与设计详解 目的:Java开源生鲜电商平台-Java后端生成Token目的是为了用于校验客户端,防止重复提交. 技术选型:用开源的JWT架构. 1. ...
- Python用摘要算法生成token及检验token
原创作者:希希大队长,blog:https://cnblogs.com/dongxixi/ # 基础版,不依赖环境 import time import base64 import hashlib c ...
- JWT生成token
1.JWT简介 JSON Web Token 简称JWT.一个JWT实际上就是一个字符串,它由三部分组成,头部.载荷与签名.JWT生成的token是这样的 2.Json Web Token(JWT)生 ...
- 生成token和获取token
1.先安装模块pip install itsdangerous 举个例子:一个用户登录成功后,讲username和token作为key,value写到redis里面,判断是否失效(1.时间到了失效,2 ...
- .NET6 JWT(生成Token令牌)
一.Net 6环境下的.net core项目里如何使用JWT. 第一步,在Nuget引入JWT.Microsoft.AspNetCore.Authentication.JwtBearer这两个NuGe ...
- .net生成随机字符串
生成随机字符串的工具类: /// <summary> /// 随机字符串工具类 /// </summary> public class RandomTools { /// &l ...
随机推荐
- Struts2--课程笔记3
获取ServletAPI: 第一种方式: //在request域中放入属性req,暂且认为getContext()获取的是request域空间,但实际不是 ActionContext.g ...
- 解题的小问题(C++)
1.判断一个数是否为整数 if(m==(int)m) 2.#include <bits/stdc++.h>using namespace std;int main(){ int n ...
- VBS脚本实例
一.一键升级哨位台核心板程序脚本. ############################################################ Set ws=WScript.Create ...
- hdu_5792_World is Exploding(树状数组+逆序对)
题目链接:hdu_5792_World is Exploding 题意: 给你一个数列,让你找有多少个(a,b,c,d)满足a≠b≠c≠d,1≤a<b≤n,1≤c<d≤n,Aa<Ab ...
- hdu_4826_Labyrinth_2014百度之星(dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4826 题意:中文题,不解释 题解:dp搞,第一列只能从上往下走,所以先算出第一列的dp数组,然后开两个 ...
- 怎么利用GitHub
我们一直用GitHub作为 免费的远程仓库,如果是个人的开源项目,放到GitHub上完全没有问题,其实GitHub就是一个开源协作社区,既可以让 别人参与你的开源项目,也可以参与别人的开源项目,在Gi ...
- mysql中出现没有权限访问或者查看全部数据库的问题
在my.cnf中mysqld目录下的 socket=/var/lib/mysql/mysql.sock一行下面添加 skip_grant_tables---------------报错退出 serv ...
- Oracle用户密码过期和用户被锁解决方法【转】
[原因/触发因素] 确定是由于Oracle11g中默认在default概要文件中设置了“PASSWORD_LIFE_TIME=180天”所导致. [影响和风险] 影响 密码过期后,业务进程连接数据库异 ...
- 转 由一次磁盘告警引发的血案:du 和 ls 的区别
如果你完全不明白或者完全明白图片含义, 那么你不用继续往下看了. 否则, 这篇文章也许正是你需要的. 背景 确切地说,不是收到的自动告警短信或者邮件告诉我某机器上的磁盘满了,而是某同学人肉发现该机器写 ...
- 【java】基础中的杂乱总结(二)
1 内部类进阶 package package8; //原则:先用内部类写 之后由于内部类匿名无法引用 用其继承的父类或实现的接口名 //再复写所有的抽象方法即可(是所有,否者还是抽象的,无法创建对象 ...