Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 14c797f

Browse filesBrowse files
committed
优化“如何产生一个随机的字母数字串作为 session 的唯一标识符”
1 parent e928fd5 commit 14c797f
Copy full SHA for 14c797f

File tree

Expand file treeCollapse file tree

2 files changed

+55
-0
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+55
-0
lines changed

‎README.md

Copy file name to clipboardExpand all lines: README.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ stackoverflow-Java-top-qa
5656
* [什么在java中存放密码更倾向于char[]而不是String](https://github.com/giantray/stackoverflow-java-top-qa/blob/master/contents/why-is-cha[]-preferred-over-String-for-passwords-in-java.md)
5757
* [如何避免在JSP文件中使用Java代码](https://github.com/giantray/stackoverflow-java-top-qa/blob/master/contents/how-to-avoid-java-code-in-jsp-files.md)
5858
* [Java 源码里的设计模式](https://github.com/giantray/stackoverflow-java-top-qa/blob/master/contents/Examples_of_GoF_Design_Patterns_in_Java's_core_libraries.md)
59+
* [如何产生一个随机的字母数字串作为 session 的唯一标识符](https://github.com/giantray/stackoverflow-java-top-qa/blob/master/contents/How_to_generate_a_random_alpha-numeric_string.md)
5960

6061
> 网络
6162
+54Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# 如何产生一个随机的字母数字串作为 session 的唯一标识符?
2+
3+
如果允许产生的随机字符串是可猜测的(随机字符串比较都短,或者使用有缺陷的随机数生成器),进而导致攻击者可能会劫持到会话的,可以使用一个相对简单随机数生成代码,如下所示:
4+
```
5+
public class RandomString {
6+
7+
private static final char[] symbols;
8+
9+
static {
10+
StringBuilder tmp = new StringBuilder();
11+
for (char ch = '0'; ch <= '9'; ++ch)
12+
tmp.append(ch);
13+
for (char ch = 'a'; ch <= 'z'; ++ch)
14+
tmp.append(ch);
15+
symbols = tmp.toString().toCharArray();
16+
}
17+
18+
private final Random random = new Random();
19+
20+
private final char[] buf;
21+
22+
public RandomString(int length) {
23+
if (length < 1)
24+
throw new IllegalArgumentException("length < 1: " + length);
25+
buf = new char[length];
26+
}
27+
28+
public String nextString() {
29+
for (int idx = 0; idx < buf.length; ++idx)
30+
buf[idx] = symbols[random.nextInt(symbols.length)];
31+
return new String(buf);
32+
}
33+
}
34+
```
35+
36+
为了安全,可以考虑使用下面这段简洁且安全的代码,不过用其作为 session 的标识符,倒显得有点大材小用了(比较耗时):
37+
```
38+
import java.security.SecureRandom;
39+
40+
public final class SessionIdentifierGenerator {
41+
private SecureRandom random = new SecureRandom();
42+
43+
public String nextSessionId() {
44+
return new BigInteger(130, random).toString(32);
45+
}
46+
}
47+
```
48+
49+
其工作原理就是,使用一个 130 位的安全的随机数生成器生成一个随机数,接着转化为 32 进制。我们知道,128 位安全随机数的生成已经是足够安全的,不过以 32 进制编码的每一个数字可编码 5 位,所以需要取大于 128 且是 5 的倍数,所以就选择了 130 位。相对于 随机 UUID 来说(在标准输出中,每个字符使用 3.4 bit,共 122 bit),每个字符使用 5 个随机的 bit 来编码的方式,显得更为简洁和高效。
50+
51+
译者注:上面两段代码,生成26位随机字符串,第一段代码每次耗时不到1ms,第二段耗时约100ms。也就是说第一段代码更快,但第二段代码更安全,但更耗时。
52+
53+
stackoverflow原链接:
54+
http://stackoverflow.com/questions/41107/how-to-generate-a-random-alpha-numeric-string

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.