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.

public class MathRandomExample {
    public static void main(String[] args) {
        double randomDouble = Math.random();
        int randomInt = (int) (randomDouble * 100); // Số ngẫu nhiên từ 0 đến 99
        System.out.println("Random double: " + randomDouble);
        System.out.println("Random int: " + randomInt);
    }
}

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.

import java.util.concurrent.ThreadLocalRandom;

public class ThreadLocalRandomExample {
    public static void main(String[] args) {
        int randomInt = ThreadLocalRandom.current().nextInt(0, 100); // Số ngẫu nhiên từ 0 đến 99
        System.out.println("ThreadLocalRandom int: " + randomInt);
    }
}

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.

import java.util.Random;

public class RandomIntsExample {
    public static void main(String[] args) {
        Random rand = new Random();
        rand.ints(5, 0, 100).forEach(System.out::println); // 5 số ngẫu nhiên từ 0 đến 99
    }
}

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.

import java.security.SecureRandom;

public class SecureRandomExample {
    public static void main(String[] args) {
        SecureRandom secureRand = new SecureRandom();
        int randomInt = secureRand.nextInt(100); // Số ngẫu nhiên từ 0 đến 99
        System.out.println("SecureRandom int: " + randomInt);
    }
}

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
  10 Java Web Framework tốt nhất
  10 lý do cho thấy tại sao bạn nên theo học ngôn ngữ lập trình Java

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 ().

Tạo số và chuỗi ngẫu nhiên trong Java

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