生成Token字串

2022-02-23 18:21:33 字數 3393 閱讀 3765

有的時候,我們需要生成一些token作為標識:如認證後的識別符號,資源的提取碼等。乙個比較常見的演算法是生成乙個guid來作為token,由於guid的隨機性和唯一性特點,作為token是乙個非常可靠的選擇。

guid是乙個128bit的陣列,為了方便攜帶,往往需要把它表述為字串的形式。一般把它表述為如下形式:。這樣有乙個弊病:太長了,那麼我們如何把它弄短點呢?

去掉不必要的修飾符,

首先可以通過去掉無意義的括號和減號來較少長度:

vartoken = guid.tostring("n");

這樣字串就成為:79faf82271944fe38c4f1d99be71bc9c。感覺還是蠻長的。

使用base64編碼來表示

前面的表示方法中,是使用的16機制來表示的,如果使用base64編碼的話,則可以進一步壓縮字串

vartoken = convert.tobase64string(guid.tobytearray()).trimend('=');

這樣字串就成為:ivj6ezrx40+mtx2zvng8na。看起來稍微好一點了。

換一種token生成方式

在使用base64方式的編碼後,token字串還是有20多位,有的時候還是嫌它長了。由於guid本身就有128bit,在要求有良好的可讀 性的前提下,很難進一步改進了。那我們如何產生更短的字串呢?還有一種方式就是較少token的長度,不用guid,而採用一定長度的隨機數,例如 64bit,再用base64編碼表示:

varrnd = newrandom();

vartokendata = newbyte[8];

rnd.nextbytes(tokendata);

vartoken = convert.tobase64string(tokendata).trimend('=');

由於這裡只用了64bit,此時得到的字串為onh0h95n7nw的形式,長度要短一半。這樣就方便攜帶多了。但是這種方式是沒有唯一性保證的。不過用來作為身份認證的方式還是可以的(如網盤的提取碼)。

更進一步

前面的演算法中,長度和隨機性倒是有了,但是沒有唯一性。對於需要唯一性的場景,則需要改寫一下token的生成演算法了,我在這裡給乙個簡單的示例:

classtoken}

這裡我的演算法非常簡單:

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作為標識:如認證後的識別符號,資源的提取碼等。乙個比較常見的演算法是生成乙個guid來作為token,由於guid的隨機性和唯一性特點,作為token是乙個非常可靠的選擇。

guid是乙個128bit的陣列,為了方便攜帶,往往需要把它表述為字串的形式。一般把它表述為如下形式:。這樣有乙個弊病:太長了,那麼我們如何把它弄短點呢?

去掉不必要的修飾符,

首先可以通過去掉無意義的括號和減號來較少長度:

vartoken = guid.tostring("n");

這樣字串就成為:79faf82271944fe38c4f1d99be71bc9c。感覺還是蠻長的。

使用base64編碼來表示

前面的表示方法中,是使用的16機制來表示的,如果使用base64編碼的話,則可以進一步壓縮字串

vartoken = convert.tobase64string(guid.tobytearray()).trimend('=');

這樣字串就成為:ivj6ezrx40+mtx2zvng8na。看起來稍微好一點了。

換一種token生成方式

在使用base64方式的編碼後,token字串還是有20多位,有的時候還是嫌它長了。由於guid本身就有128bit,在要求有良好的可讀 性的前提下,很難進一步改進了。那我們如何產生更短的字串呢?還有一種方式就是較少token的長度,不用guid,而採用一定長度的隨機數,例如 64bit,再用base64編碼表示:

varrnd = newrandom();

vartokendata = newbyte[8];

rnd.nextbytes(tokendata);

vartoken = convert.tobase64string(tokendata).trimend('=');

由於這裡只用了64bit,此時得到的字串為onh0h95n7nw的形式,長度要短一半。這樣就方便攜帶多了。但是這種方式是沒有唯一性保證的。不過用來作為身份認證的方式還是可以的(如網盤的提取碼)。

更進一步

前面的演算法中,長度和隨機性倒是有了,但是沒有唯一性。對於需要唯一性的場景,則需要改寫一下token的生成演算法了,我在這裡給乙個簡單的示例:

classtoken}

這裡我的演算法非常簡單:

token由兩部分組成,32位的隨機數+32位的序列

由序列保證唯一性,由隨機數保證隨機性。

組合後再進行一次shuffle。

當然,我這個演算法也有一定的侷限性,如:

token只能在4g範圍內保證唯一

token只能在上下文中保證唯一

token不是完全隨機的

要解決這幾個問題,實現在任何時候,任何位置,任何情況下產生的token都具有唯一性和隨機性也是能做到的。但是,要知道的是,任何功能都是附有

一定的代價的。這些條件往往帶來的代價就是token長度增加——guid就是滿足這一系列條件的演算法。軟體的世界沒有銀彈,我們只要在一定範圍內找到能

解決問題的方法即可。

system.guid guid = system.guid.newguid(); //guid 型別                  string strguid = system.guid.newguid().tostring(); //直接返回字串型別   

生成字串

description 假設乙個字串只由字元 0 1 組成,其中字元 表示該字元可由字元 0 或 1 替代。現有一些字串,根據這些字串生成所有可生成的字串。如 可生成 可生成注意後乙個例子中 01 並沒有生成新的字串。input 輸入包含多組測試資料。每組資料的第一行是兩個整數m,n 1 m 15,...

生成字串

從空串出發,每次在字串中間插入乙個或多個相同的字母,插入的字母可以在頭部和尾部。求出最少的次數。動態規劃,逆向進行,考慮首尾。include include include include include include include includeusing namespace std cons...

生成隨機字串

原文出處 估摸著以後極有可能使用到,於是寫了乙個生成隨機字串的函式。可以自定義生成規則,生成字串長度。模仿了ms的函式風格,生成規則使用巨集的或且規則,返回值使用了布林型。這裡使用布林返回可能作用不大。直接貼 吧,同樣是兩個檔案。randomstring.h pragma once define r...