Tạo random số và chuỗi ngẫu nhiên trong Java
Bài viết được sự cho phép của tác giả Giang Phan
Trong thế giới lập trình, việc tạo số ngẫu nhiên là một yêu cầu cơ bản và quan trọng, ảnh hưởng trực tiếp đến chất lượng và tính ngẫu nhiên của dữ liệu. Java, với sự đa dạng và mạnh mẽ của mình, cung cấp nhiều cách để sinh số ngẫu nhiên. Bài viết này sẽ giới thiệu ba phương pháp chính để tạo số ngẫu nhiên trong Java.
Hướng dẫn tạo số ngẫu nhiên bằng Java chi tiết
Để tạo một trình tạo số ngẫu nhiên (generator), đơn giản chỉ việc tạo một new instance của Random.
Random generator =
new
Random();
Khi sử dụng hàm tạo này, bạn sẽ nhận ra rằng các trình tạo số ngẫu nhiên thuật toán không thực sự ngẫu nhiên, chúng thực sự là các thuật toán tạo ra một chuỗi số cố định nhưng trông ngẫu nhiên.
Khi tạo một generator, nó sẽ khởi tạo chuỗi của nó từ một giá trị được gọi là “seed” của nó. Khi chúng ta sử dụng constructor không có tham số, nó sẽ tạo seed có một giá trị khác biệt với bất kỳ lời gọi nào khác của constructor này. Nhưng chúng ta không kiểm soát được giá trị đó là gì, hoặc thậm chí đảm bảo hoàn toàn rằng nó sẽ khác với seed được sử dụng bởi các lời gọi khác trên constructor này.
Nếu thích, chúng ta cũng có thể chỉ định một giá trị bất kỳ thuộc kiểu “long” để khởi tạo cho seed. Ví dụ:
Random generator =
new
Random(
19900828
);
Sau khi đã có generator, gọi các phương thức nextXxx() để tạo các giá trị ngẫu nhiên:
- nextInt() : trả về một số ngẫu nhiên trong khoảng giá trị của int value (từ -2^31 đến 2^31-1).
- nextInt(maxNumber) : trả về một số int ngẫu nhiên từ 0 đến giá trị < maxNumber.
- nextLong() : trả về một số ngẫu nhiên kiểu long. Vì Random sử dụng giá trị seed chỉ 48bits, nên thuật toán random không thể trả về tất cả các giá trị thuộc kiểu long.
- nextFloat(): trả về một số ngẫu nhiên trong khoảng 0.0 và <1.0
- nextDouble() : tương tự như nextFloat() như độ dài phần thập phân lớn hơn.
- nextBoolean() : trả về giá trị true, false ngẫu nhiên.
Ví dụ giới hạn giá trị Random Number
Đôi khi chúng ta cần số ngẫu nhiên nằm trong một phạm vi khác nhau. Chúng ta có thể làm cho các số ngẫu nhiên nằm trong một phạm vi rộng hơn hoặc hẹp hơn bằng cách nhân chúng với một hệ số tỷ lệ. Chúng ta cũng có thể đặt các số ngẫu nhiên nằm trong một phạm vi được chuyển sang các số lớn hơn hoặc nhỏ hơn so với ban đầu bằng cách cộng thêm (hoặc trừ) một phần bù từ các số ngẫu nhiên.
Ví dụ 1: chúng ta có một game có 4 người chơi, mỗi người có 1 số từ một đến 4. Chương trình của chúng ta sẽ random từ 1 đến 4 để lựa chọn người may mắn có số trùng với số được random. Đơn giản chỉ việc gọi hàm nextInt(4), hàm này sẽ trả về giá trị từ 0 đến 3, nên chúng ta cần cộng thêm 1 để có kết quả như ý muốn.
int value = generator.nextInt(4) + 1;
Ví dụ 2: Cần vẽ random một line có góc từ 0 đến 360 độ.
double value = generator.nextDouble() * 360.0;
Ví dụ 3: Random int number trong khoảng được chỉ định.
int value = generator.nextInt((max - min) + 1) + min;
Ví dụ 4: Trong một số ứng dụng đăng nhập bằng số điện thoại như Google, sau khi nhập số điện thoại, Google sẽ gửi một mã xác nhận số điện thoại gồm 6 số ngẫu nhiên. Chúng ta cũng có thể tạo số ngẫu nhiên này với Random.
int code = (int) Math.floor(((Math.random() * 899999) + 100000));
Lưu ý: Instances của java.util.Random là Thread safe. Tuy nhiên, việc sử dụng đồng thời cùng một đối tượng java.util.Random trong môi trường đa luồng (multi-thread) có thể gặp phải sự tranh chấp và hiệu suất kém. Thay vào đó hãy xem xét sử dụng ThreadLocalRandom trong các thiết kế đa luồng. Nếu cần Security random có thể sử dụng SecureRandom.
Tuyển dụng Java không yêu cầu kinh nghiệm
Các phương pháp tạo số random trong Java
Để tạo random một số ngẫu nhiên trong Java, chúng ta có thể sử dụng các hàm random trong Math class và Random class mà Java đã hỗ trợ sẵn.
Random số trong Java bằng Random class
Trong Java để tạo một số ngẫu nhiên chúng ta có thể sử dụng class java.util.Random
đã được hợp trong JDK. Class này cung cấp nhiều phương thức để tạo các kiểu số ngẫu nhiên khác nhau, chẳng hạn như như int
, float
, long
, và boolean
.
import java.util.Random;
public class RandomExample {
public static void main(String[] args) {
Random rand = new Random();
int randomInt = rand.nextInt(100); // Số ngẫu nhiên từ 0 đến 99
System.out.println("Random int: " + randomInt);
}
}
Sử dụng phương pháp Math.random()
Phương pháp Math.random()
trả về một giá trị double ngẫu nhiên từ 0.0 đến 1.0.
Sử dụng lớp java.util.concurrent.ThreadLocalRandom
Lớp ThreadLocalRandom
cung cấp một cách hiệu quả hơn để tạo số ngẫu nhiên trong các ứng dụng đa luồng.
Sử dụng phương pháp java.util.Random.ints()
Phương pháp ints()
của lớp Random
cho phép tạo ra một luồng các số nguyên ngẫu nhiên.
Sử dụng lớp java.security.SecureRandom
Lớp SecureRandom
cung cấp số ngẫu nhiên với độ bảo mật cao, thường được dùng trong các ứng dụng yêu cầu tính ngẫu nhiên mạnh mẽ như mật mã học.
Tạo chuỗi ngẫu nhiên – Random string
Có nhiều trường hợp chúng ta cần tạo chuỗi ngẫu nhiên, chẳng hạn tạo ra mã captcha để chống spam, gửi mã code xác nhận tài khoản, …. Có nhiều cách để tạo chuỗi ngẫu nhiên, trong bài này tôi sẽ hướng dẫn các bạn tự tạo chuỗi ngẫu nhiên và sử dụng thư viện Apache common.
Tự tạo chuỗi ngẫu nhiên
Để tạo một chuỗi ngẫu nhiên, chúng ta sẽ định nghĩa một chuỗi các ký tự được phép xuất hiện trong chuỗi ngẫu nhiên. Sau đó sẽ sử dụng Random để tạo một giá trị index ngẫu nhiên từ chuỗi đã định nghĩa trước đó. Cứ thực hiện random index và truy xuất ký tự từ index cho đến khi đầy đủ số lượng ký tự mong muốn.
Trong ví dụ này, tôi sẽ tạo 2 phương thức:
- randomAlphaNumeric(): Tạo một chuỗi ngẫu nhiên chỉ bao gồm các ký tự từ a-z, A-Z và 0-9, không bao gồm các ký tự đặc biệt.
- randomPassword(): Tạo một chuỗi password ngẫu nhiên bao gồm ít nhất 1 ký tự đặc biệt và 1 ký tự số.
package
com.gpcoder.random;
import
java.util.ArrayList;
import
java.util.Collections;
import
java.util.List;
import
java.util.Random;
import
java.util.function.Consumer;
public
class
RandomStringExmple {
private
static
final
String alpha =
"abcdefghijklmnopqrstuvwxyz"
;
// a-z
private
static
final
String alphaUpperCase = alpha.toUpperCase();
// A-Z
private
static
final
String digits =
"0123456789"
;
// 0-9
private
static
final
String specials =
"~=+%^*/()[]{}/!@#$?|"
;
private
static
final
String ALPHA_NUMERIC = alpha + alphaUpperCase + digits;
private
static
final
String ALL = alpha + alphaUpperCase + digits + specials;
private
static
Random generator =
new
Random()
/**
* Random string with a-zA-Z0-9, not included special characters
*/
public
String randomAlphaNumeric(
int
numberOfCharactor) {
StringBuilder sb =
new
StringBuilder();
for
(
int
i =
0
; i < numberOfCharactor; i++) {
int
number = randomNumber(
0
, ALPHA_NUMERIC.length() -
1
);
char
ch = ALPHA_NUMERIC.charAt(number);
sb.append(ch);
}
return
sb.toString();
}
/**
* Random string password with at least 1 digit and 1 special character
*/
public
String randomPassword(
int
numberOfCharactor) {
List<String> result =
new
ArrayList<>();
Consumer<String> appendChar = s -> {
int
number = randomNumber(
0
, s.length() -
1
);
result.add(
""
+ s.charAt(number));
};
appendChar.accept(digits);
appendChar.accept(specials);
while
(result.size() < numberOfCharactor) {
appendChar.accept(ALL);
}
Collections.shuffle(result, generator);
return
String.join(
""
, result);
}
public
static
int
randomNumber(
int
min,
int
max) {
return
generator.nextInt((max - min) +
1
) + min;
}
public
static
void
main(String a[]){
int
numberOfCharactor =
8
;
RandomStringExmple rand =
new
RandomStringExmple();
System.out.println(
"randomString1: "
+ rand.randomAlphaNumeric(numberOfCharactor));
System.out.println(
"randomString1: "
+ rand.randomAlphaNumeric(numberOfCharactor));
System.out.println(
"randomString1: "
+ rand.randomAlphaNumeric(numberOfCharactor));
System.out.println(
"randomPassword1: "
+ rand.randomPassword(numberOfCharactor));
System.out.println(
"randomPassword2: "
+ rand.randomPassword(numberOfCharactor));
}
}
Chạy chương trình trên nhiều lần, chúng ta sẽ thấy các kết quả khác nhau:
randomString1: 65cihDTo
randomString1: GbEMJBVH
randomString1: WJF7hZ3c
randomPassword1: #f|XD/W3
randomPassword2: |M$=}=2A
Sử dụng lớp commons.lang3.text.RandomStringUtils
Một số phương thức hỗ trợ tạo chuỗi và số ngẫu nhiên trong lớp RandomStringUtils:
- random(int count) : Tạo một chuỗi ngẫu nhiên có chiều dài là số ký tự được chỉ định, không giới hạn loại ký tự được trả về.
- randomAscii(int count) : Tạo một chuỗi ngẫu nhiên có chiều dài là số ký tự được chỉ định, bao gồm các ký tự có giá trị ASCII từ 32 đến 126.
- randomNumeric(int count) : Tạo một chuỗi số ngẫu nhiên có chiều dài là số ký tự được chỉ định, bao gồm các ký tự số 0-9.
- randomAlphabetic(int count) : Tạo một chuỗi số ngẫu nhiên có chiều dài là số ký tự được chỉ định, bao gồm các ký tự chữ Latin (a-z, A-Z).
- randomAlphanumeric(int count) : Tạo một chuỗi số ngẫu nhiên có chiều dài là số ký tự được chỉ định, bao gồm các ký tự chữ Latin (a-z, A-Z) và số 0-9.
- random(int count, String input) : Tạo một chuỗi số ngẫu nhiên có chiều dài là số ký tự được chỉ định, chỉ bao gồm các ký tự được xác định trong input.
Ví dụ:
package
com.gpcoder;
import
org.apache.commons.lang3.RandomStringUtils;
public
class
RandomStringUtilsExample {
public
static
void
main(String[] args) {
System.out.println(RandomStringUtils.random(
4
));
//
System.out.println(RandomStringUtils.random(
6
));
// 㚔쬩́㽩
System.out.println(RandomStringUtils.randomAscii(
4
));
// qe51
System.out.println(RandomStringUtils.randomAscii(
6
));
// MqQ^X\
System.out.println(RandomStringUtils.randomNumeric(
4
));
// 9808
System.out.println(RandomStringUtils.randomNumeric(
6
));
// 338756
System.out.println(RandomStringUtils.randomAlphabetic(
4
));
// kvMu
System.out.println(RandomStringUtils.randomAlphabetic(
6
));
// PeykyQ
System.out.println(RandomStringUtils.randomAlphanumeric(
4
));
// MavC
System.out.println(RandomStringUtils.randomAlphanumeric(
6
));
// fR2BEf
String input =
"abcd1234!@#$%^&*()-=_+;:<>,.?/"
;
System.out.println(RandomStringUtils.random(
4
, input));
// 1)+(
System.out.println(RandomStringUtils.random(
6
, input));
// -c=,a,
}
}
Sử dụng java.util.UUID
UUID (Universally Unique Identifier) hay còn được biết đến như là GUID (Globally Unique Identifier), là một chuỗi đại diện cho một mã định danh duy nhất, không thể thay đổi (immutable), và có giá trị dài 128 bit.
UUID được sử dụng để tạo tên file ngẫu nhiên, id session trong ứng dụng web, id transaction, …
Phương thức java.util.UUID.randomUUID() được sử dụng để sinh ra một chuỗi ngẫu nhiên có độ dài 32 ký tự (128 bit) được biểu diễn ở hệ hệ thập lục phân (hex: 0-9A-F) và 4 ký tự phân tách (–).
Ví dụ:
UUID uuid = UUID.randomUUID();
System.out.println(
"UUID: "
+ uuid.toString());
System.out.println(
"variant: "
+ uuid.variant());
System.out.println(
"version: "
+ uuid.version());
Chạy chương trình, chúng ta có kết quả như sau:
UUID: ef41d4cb-5d1b-4a83-a4c1-f1397e3fcdb7
variant:
2
version:
4
Như vậy chúng mình đã cùng nhau tìm hiểu các cách tạo số và chuỗi kí tự random trong Java. Cảm ơn bạn đọc!
Bài viết gốc được đăng tải tại gpcoder.com
Xem thêm các việc làm Java hấp dẫn tại TopDev
- T Từ khóa final trong Java
- R RxJava – Thời đại lập trình Reactive programming ứng dụng Android đã tới
- J Java roadmap cho newbie – Từ số 0 đến chuyên nghiệp
- T Top các Framework Java Backend phổ biến cho anh em Developer
- T Tìm hiểu về lớp HashMap trong Java: Các hoạt động và cách dùng
- L Lập trình Android bằng Java: Hướng dẫn toàn diện
- J Java Super là gì? Sự khác biệt giữa Java Super và Java thông thường
- K Khai báo phương thức overloading trong Java
- J Java Sleep: Kỹ thuật ngủ luồng trong lập trình Java
- S Sử dụng subString trong xử lý văn bản trong Java