我想随机生成唯一且安全的字符串,我想随着时间的推移而做。我想为我的使用选择尽可能短的长度(足够大,以便随机尝试失败并且有很好的机会)。我也希望这个过程很快。使用以下代码并测试它的唯一性,重复发生的时间比我预期的要快。我不确定是否有任何问题。
P.S。:使用池生成数字是否安全?
P.P.S:我不想在字母表中添加' - '和'_'。是否值得删除它?
string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
string Random(int length,string alphabet)
{
StringBuilder result = new StringBuilder();
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
for (int i = 0; i < length; i++)
{
byte[] buffer = new byte[sizeof(uint)];
rng.GetBytes(buffer);
uint num = BitConverter.ToUInt32(buffer, 0);
result.Append(alphabet[(int)(num % (uint)alphabet.Length)]);
}
}
return result.ToString();
}
答案 0 :(得分:0)
通常,在Alphabet
中,每个字符都有6位“信息”(有64个字符)。所以长度= 10的字符串有60位信息。对于sq {(2 ^ 60)之后的birthday paradox,即2 ^ 30,你应该有0.5次碰撞的可能性(50%)。 2 ^ 30相当大,但如果字符数较少,那么碰撞就会发生得更早。
请注意,可以在代码中进行可能的优化(预先分配StringBuilder的“正确”长度)并且存在错误:
public const string BaseAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
public static string Random(int length, string alphabet = BaseAlphabet)
{
StringBuilder result = new StringBuilder(length);
uint maxValue = (uint)((((ulong)uint.MaxValue) + 1) / (uint)alphabet.Length * (uint)alphabet.Length);
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
for (int i = 0; i < length; i++)
{
uint num;
do
{
byte[] buffer = new byte[sizeof(uint)];
rng.GetBytes(buffer);
num = BitConverter.ToUInt32(buffer, 0);
}
while (num >= maxValue);
result.Append(alphabet[(int)(num % (uint)alphabet.Length)]);
}
}
return result.ToString();
}
在您编写的代码中,某些字符可能比其他字符更可能。这是因为if {uint.MaxValue + 1
)(由rng生成的整个可能数字范围)不能被alphabet.Length
完全整除,那么alphabet
末尾的字符可能比var container;
class LandingPage extends React.Component {
constructor(props) {
super(props);
}
listTaskLists = () => {
console.log(window.gapi.client.tasks);
window.gapi.client.tasks.tasklists.list({
'maxResults': 10
}).then(function(response) {
var l = '';
var taskLists = response.result.items;
if (taskLists && taskLists.length > 0) {
for (var i = 0; i < taskLists.length; i++) {
var taskList = taskLists[i];
console.log(taskList.title);
}
} else {
console.log("TNo Tasks")
}
});
}
componentDidMount() {
container = this;
console.log("hg");
console.log(window.gapi.client.tasks);
// window.gapi.client.tasks.tasklists.list({
// 'maxResults': 10
// }).then(function(response) {
// // appendPre('Task Lists:');
// var l = '';
// var taskLists = response.result.items;
// if (taskLists && taskLists.length > 0) {
// for (var i = 0; i < taskLists.length; i++) {
// var taskList = taskLists[i];
// console.log(taskList.title);
// }
// } else {
// console.log("TNo Tasks")
// }
// });
}
render () {
return (
<div id = "LandingPageMain" style =
{{height: '414px'}}>
<Grid container wrap="nowrap" spacing={40}
alignContent="center" justify ="center"
alignItems="center" direction="column">
<Grid item>
<img style={{width: '80px', height: '80px'}} src={Icon}/>
</Grid>
<Grid item>
<Typography variant="display1" align="center" component="h3">
TASKS
</Typography>
</Grid>
<Grid item>
<Link to={{ pathname: "/TasksPage", state: { listId: 'MTI1NzMwMjIzNjgxNDAwMDExMjM6MDow'} }}>
<Button variant="contained">TasksPage</Button>
</Link>
</Grid>
<Grid item>
<Link to = "/ListsPage">
<Button variant="contained">ListsPage</Button>
</Link>
</Grid>
<Grid item>
<Button variant="contained" onClick={this.listTaskLists}>Test</Button>
</Grid>
</Grid>
</div>
);
}
}
更不可能。开头的人物。