สร้างตัวเลขสุ่มแบบสุ่มใน JavaScript ในช่วงที่ต้องการหรือไม่


1955

ฉันจะสร้างตัวเลขสุ่มระหว่างทั้งสองตัวแปรที่ระบุใน JavaScript เช่นx = 4และy = 8เอาท์พุทจะใด ๆ4, 5, 6, 7, 8?


1
นี่คือส่วนสำคัญที่มีประโยชน์: gist.github.com/kerimdzhanov/7529623
Dan KK

9
หมายเหตุด้านข้าง: สำหรับผู้ที่ใช้ npm และกำลังมองหาโซลูชันที่รวดเร็วน่าเชื่อถือและพร้อมใช้งานจะมีlodash.randomที่สามารถใช้งานได้ง่ายด้วยการใช้พื้นที่ขนาดเล็กมาก
โนบิตะ

ถ้ามันจะต้องปลอดภัย crypto ปลอดภัยdeveloper.mozilla.org/en-US/docs/Web/API/RandomSource/?hl=th
มีความสุข

คำตอบ:


3832

มีตัวอย่างบางส่วนในหน้าMozilla Developer Network :

/**
 * Returns a random number between min (inclusive) and max (exclusive)
 */
function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}

/**
 * Returns a random integer between min (inclusive) and max (inclusive).
 * The value is no lower than min (or the next integer greater than min
 * if min isn't an integer) and no greater than max (or the next integer
 * lower than max if max isn't an integer).
 * Using Math.round() will give you a non-uniform distribution!
 */
function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

นี่คือตรรกะที่อยู่เบื้องหลัง มันเป็นกฎง่ายๆสามข้อ:

Math.random()ส่งคืนค่าNumberระหว่าง 0 (รวม) และ 1 (พิเศษ) ดังนั้นเราจึงมีช่วงเวลาเช่นนี้:

[0 .................................... 1)

ตอนนี้เราต้องการหมายเลขระหว่างmin(รวม) และmax(พิเศษ):

[0 .................................... 1)
[min .................................. max)

เราสามารถใช้Math.randomเพื่อรับผู้สื่อข่าวในช่วงเวลา [min, max) แต่ก่อนอื่นเราควรคำนึงถึงปัญหาเล็กน้อยโดยการลบออกminจากช่วงเวลาที่สอง:

[0 .................................... 1)
[min - min ............................ max - min)

สิ่งนี้ให้:

[0 .................................... 1)
[0 .................................... max - min)

ตอนนี้เราอาจนำไปใช้Math.randomและจากนั้นคำนวณผู้สื่อข่าว ลองเลือกหมายเลขสุ่ม:

                Math.random()
                    |
[0 .................................... 1)
[0 .................................... max - min)
                    |
                    x (what we need)

ดังนั้นเพื่อที่จะค้นหาxเราจะทำ:

x = Math.random() * (max - min);

อย่าลืมเพิ่มminกลับเพื่อให้ได้ตัวเลขในช่วง [min, max):

x = Math.random() * (max - min) + min;

นั่นเป็นฟังก์ชั่นแรกจาก MDN ตัวที่สองคืนค่าจำนวนเต็มระหว่างminและmaxรวมทั้งสองอย่าง

ตอนนี้สำหรับการรับจำนวนเต็มคุณสามารถใช้round, หรือceilfloor

คุณสามารถใช้Math.round(Math.random() * (max - min)) + minสิ่งนี้ได้ แต่ให้การแจกแจงแบบไม่สม่ำเสมอ ทั้งสองminและmaxมีโอกาสเพียงประมาณครึ่งที่จะหมุน:

min...min+0.5...min+1...min+1.5   ...    max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘    Math.round()
   min          min+1                          max

ด้วยการยกเว้นจากช่วงเวลาก็มีโอกาสแม้แต่น้อยที่จะม้วนกว่าmaxmin

กับMath.floor(Math.random() * (max - min +1)) + minคุณมีการกระจายอย่างสมบูรณ์แบบแม้กระทั่ง

min.... min+1... min+2 ... max-1... max.... max+1 (is excluded from interval)
|        |        |         |        |        |
└───┬───┘└───┬───┘└─── ... ┘└───┬───┘└───┬───┘    Math.floor()
   min     min+1               max-1    max

คุณไม่สามารถใช้ceil()และ-1ในสมการนั้นได้เนื่องจากmaxตอนนี้มีโอกาสน้อยลงเล็กน้อยในการหมุน แต่คุณสามารถหมุนmin-1ผลลัพธ์ที่ไม่ต้องการได้เช่นกัน


10
มันเพียง แต่ทำเพราะมันโทรfloorซึ่งรอบลง
Josh Stodola

4
@ thezachperson31 คุณสามารถใช้roundแต่ทั้งคู่minและmaxมีโอกาสเพียงครึ่งเดียวที่จะหมุนได้เหมือนกับหมายเลขอื่น ๆ ceilคุณยังสามารถลบคุณหนึ่งและใช้เวลา อย่างไรก็ตามการทำเช่นนี้จะทำให้maxหมายเลขมีโอกาสน้อยลงในการหมุนเนื่องจาก[0,1)ช่วงเวลาน้อยที่สุด
Christoph

12
ฉันได้สร้าง JSFiddle หากใครต้องการทดสอบการกระจายของวิธีนี้: jsfiddle.net/F9UTG/1
ahren

8
@ JackFrost ใช่นั่นถูกต้องแล้ว คุณไม่ได้โง่คุณเพิ่งจะเรียนรู้ :)
425416 Ionuț G. Stan

3
คำถามนี้เก่า แต่การเข้าใจคำตอบนี้ทำให้ฉันใช้เวลามากเกินไป Oo ฉันคิดว่าการขยาย math.random ใน JavaScript เวอร์ชันถัดไปน่าจะมีประโยชน์
Jonathan Ortega

527
var randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;

19
ฉันรู้ว่านี่เป็นคำตอบที่เก่ามาก แต่การใช้(Math.random() * (maximum - minimum + 1) ) << 0นั้นเร็วกว่า
Ismael Miguel

11
@IsmaelMiguel ใช้ประกอบการไบนารี ( x << 0, x | 0, ~~x) แทนการMath.floor()แปรรูปxเป็นสองส่วนเติมเต็มกับช่วงที่มีขนาดเล็กกว่าNumber.MAX_SAFE_INTEGER(เทียบกับ2³²⁻¹2⁵³) จึงทำให้คุณต้องใช้ด้วยความระมัดระวัง!
le_m

@IsmaelMiguel Yo ฉันลองใช้วิธีการของคุณในคอนโซลและสุ่มได้ค่าลบ! Math.randRange = (ต่ำสุด, สูงสุด) => (Math.random () * (สูงสุด - ขั้นต่ำ + 1)) << 0 Math.randRange (2,657348096152) -1407373159
bluejayke

@bluejayke เนื่องจาก 657348096152 (100110010000110011111111111111110000000011000 ในรูปแบบไบนารี) มี 40 บิตในขณะที่เลขคณิตคิดเลขบิตใช้ 32 บิต ถ้าคุณ657348096152|0ได้ 218099864 (110011111111111111000010011000 เป็นเลขฐานสอง)
Ismael Miguel

1
นี่คือคำตอบที่ฉลาด ทำให้ช่วงภายใน [min, max + 1) บรรลุผลตามที่ต้องการจริงของ [min, max] ทั้งคู่ ขอบคุณ! :)
Mladen B.

135

Math.random ()

ส่งคืนตัวเลขสุ่มจำนวนเต็มระหว่างนาที ( รวม ) และสูงสุด ( รวมอยู่ด้วย ):

function randomInteger(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

หรือตัวเลขสุ่มใด ๆระหว่างขั้นต่ำ ( รวม ) และสูงสุด ( ไม่รวม ):

function randomNumber(min, max) {
  return Math.random() * (max - min) + min;
}

ตัวอย่างที่เป็นประโยชน์ (จำนวนเต็ม):

// 0 -> 10
Math.floor(Math.random() * 11);

// 1 -> 10
Math.floor(Math.random() * 10) + 1;

// 5 -> 20
Math.floor(Math.random() * 16) + 5;

// -10 -> (-2)
Math.floor(Math.random() * 9) - 10;

** และน่าจดจำเสมอ (Mozilla):

Math.random () ไม่ได้ให้ตัวเลขสุ่มที่ปลอดภัยเข้ารหัส อย่าใช้สิ่งใดก็ตามที่เกี่ยวข้องกับความปลอดภัย ใช้ Web Crypto API แทนและแม่นยำมากขึ้นกับวิธี window.crypto.getRandomValues ​​()


56
function getRandomizer(bottom, top) {
    return function() {
        return Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom;
    }
}

การใช้งาน:

var rollDie = getRandomizer( 1, 6 );

var results = ""
for ( var i = 0; i<1000; i++ ) {
    results += rollDie() + " ";    //make a string filled with 1000 random numbers in the range 1-6.
}

ทำให้พังถล่ม:

เราจะส่งคืนฟังก์ชัน (ยืมจากการเขียนโปรแกรมฟังก์ชั่น) ที่เมื่อเรียกว่าจะส่งคืนจำนวนเต็มแบบสุ่มระหว่างค่าbottomและtopรวม เราพูดว่า "รวม" เพราะเราต้องการรวมทั้งด้านล่างและด้านบนในช่วงของตัวเลขที่สามารถส่งคืนได้ วิธีนี้getRandomizer( 1, 6 )จะส่งคืน 1, 2, 3, 4, 5 หรือ 6

(ด้านล่างคือจำนวนที่ต่ำกว่าด้านบนเป็นจำนวนที่มากกว่า)

Math.random() * ( 1 + top - bottom )

Math.random()ผลตอบแทนที่ได้สุ่มคู่ระหว่าง 0 และ 1, และถ้าเราคูณด้วยหนึ่งบวกความแตกต่างระหว่างtopและbottomเราจะได้รับบางคู่ระหว่างและ01+b-a

Math.floor( Math.random() * ( 1 + top - bottom ) )

Math.floorปัดเศษตัวเลขลงให้เป็นจำนวนเต็มที่ใกล้ที่สุด ดังนั้นตอนนี้เรามีจำนวนเต็มทั้งหมดระหว่างและ0 top-bottomคนที่ 1 ดูสับสน แต่มันต้องอยู่ที่นั่นเพราะเราปัดเศษลงเสมอดังนั้นหมายเลขสูงสุดจึงไม่สามารถเข้าถึงได้โดยที่ไม่มี ทศนิยมสุ่มเราสร้างความต้องการที่จะอยู่ในช่วง0การ(1+top-bottom)เพื่อให้เราสามารถปัดเศษลงและได้รับการ int ในช่วง0ที่จะtop-bottom

Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom

รหัสในตัวอย่างก่อนหน้านี้ทำให้เรามีจำนวนเต็มในช่วง0และtop-bottomดังนั้นสิ่งที่เราต้องทำตอนนี้คือการเพิ่มbottomไปที่ผลลัพธ์เพื่อรับจำนวนเต็มในช่วงbottomและtopรวม : D


หมายเหตุ: หากคุณส่งผ่านค่าที่ไม่เป็นจำนวนเต็มหรือจำนวนที่มากกว่าก่อนคุณจะได้รับพฤติกรรมที่ไม่พึงประสงค์ แต่ถ้าใครร้องขอมันฉันจะไม่เจาะเข้าไปในรหัสตรวจสอบการโต้แย้งว่ามันค่อนข้างไกลจากเจตนาของคำถามเดิม .


1
ฉันรู้ว่านี่คือประมาณ2½ปีต่อมา แต่ด้วยอินพุต 1 และ 6 ฟังก์ชั่นของคุณจะส่งกลับค่า 1,2,3,4 และ 5 แต่ไม่เคยมี 6 เช่นที่มันจะเป็น "รวม"
ช่วง

9
@ บาง, มันอาจจะแย่กว่านั้นฉันคือ2½ปี + 1 วันต่อมา ^^
ajax333221

+1 ฉันทดสอบรหัสของคุณดูเหมือนว่าจะสร้างค่าที่ถูกต้อง โครงสร้างความคิดสร้างสรรค์ในการจัดการสถานการณ์ที่คงที่ซึ่งอาจมีการซ้ำหลายครั้งในรหัส
Chris

ทำไมคุณมีฟังก์ชั่นภายในฟังก์ชั่นนี้?
Alph.Dev

1
@ Alph.Dev เพื่อ decouple ตรรกะที่ใช้ตัวสร้างตัวเลขสุ่มจากตรรกะที่ตัดสินใจว่าสิ่งที่การกระจายจำนวนสุ่มที่จะใช้ เมื่อรหัสที่ใช้ตัวสร้างตัวเลขสุ่มยอมรับว่าเป็นพารามิเตอร์ (ฟังก์ชัน 0 อาร์กิวเมนต์ที่ส่งกลับหมายเลขสุ่มใหม่เสมอ) มันสามารถทำงานกับตัวสร้างตัวเลขสุ่มชนิดใดก็ได้
Gordon Gustafson

31
function randomRange(min, max) {
  return ~~(Math.random() * (max - min + 1)) + min
}

ทางเลือกถ้าคุณใช้Underscore.jsคุณสามารถใช้ได้

_.random(min, max)

1
ขีดล่างจริง ๆ แล้วมี_.uniqueId()ฟังก์ชันที่คุณสามารถเรียกใช้โมเดลฝั่งไคลเอ็นต์
obfk

ใช้ประกอบการไบนารี ( x << 0, x | 0, ~~x) แทนการMath.floor()แปรรูปxเป็นสองส่วนเติมเต็มกับช่วงที่มีขนาดเล็กกว่าNumber.MAX_SAFE_INTEGER(เทียบกับ2³²⁻¹2⁵³) จึงทำให้คุณต้องใช้ด้วยความระมัดระวัง!
le_m

31

ส่งคืนตัวเลขสุ่มระหว่าง 1 ถึง 10:

Math.floor((Math.random()*10) + 1); 

ส่งคืนตัวเลขสุ่มระหว่าง 1 ถึง 100:

Math.floor((Math.random()*100) + 1)

"ระหว่าง" รวมหรือไม่รวมของคุณคืออะไร เช่นมันคือ [1,10], [1,10), (1,10] หรือ (1,10)?
evandrix

1
มันรวมบางส่วน: [1, *)
Ivan Z

ความต้องการ +1 ในตอนท้ายของฟังก์ชันคืออะไร มันทำงานได้อย่างสมบูรณ์แบบที่ฉันเดา
Shachi

18

หากคุณต้องการตัวแปรระหว่าง 0 ถึงสูงสุดคุณสามารถใช้:

Math.floor(Math.random() *  max);

เป็นแบบรวมสูงสุดหรือแบบเอกสิทธิ์>>
ต้นไม้

2
@Tree ที่ใช้ Math.floor max เป็นเอกสิทธิ์ ถ้าคุณต้องการให้ max รวมอยู่ด้วยคุณสามารถใช้ Math.round
ลุค

14

คำตอบอื่น ๆ ไม่บัญชีสำหรับพารามิเตอร์ที่เหมาะสมอย่างสมบูรณ์แบบของและ0 1แต่คุณควรใช้round แทนของceilหรือfloor:

function randomNumber(minimum, maximum){
    return Math.round( Math.random() * (maximum - minimum) + minimum);
}

console.log(randomNumber(0,1));  # 0 1 1 0 1 0
console.log(randomNumber(5,6));  # 5 6 6 5 5 6
console.log(randomNumber(3,-1)); # 1 3 1 -1 -1 -1

1
คำตอบของคุณเป็นจริง แต่ฉันคิดว่าตัวอย่างของคุณผิด .. console.log(randomNumber(5,6)); # 9 6 6 5 7 79 และ 7 มาระหว่าง 5 และ 6 หรือไม่? ...... คุณควรแก้ไขหรืออธิบาย ..
Sachin

12

นี่คือการใช้ MS DotNet ในชั้นเรียนแบบสุ่มใน javascript-

var Random = (function () {
function Random(Seed) {
    if (!Seed) {
        Seed = this.milliseconds();
    }
    this.SeedArray = [];
    for (var i = 0; i < 56; i++)
        this.SeedArray.push(0);
    var num = (Seed == -2147483648) ? 2147483647 : Math.abs(Seed);
    var num2 = 161803398 - num;
    this.SeedArray[55] = num2;
    var num3 = 1;
    for (var i_1 = 1; i_1 < 55; i_1++) {
        var num4 = 21 * i_1 % 55;
        this.SeedArray[num4] = num3;
        num3 = num2 - num3;
        if (num3 < 0) {
            num3 += 2147483647;
        }
        num2 = this.SeedArray[num4];
    }
    for (var j = 1; j < 5; j++) {
        for (var k = 1; k < 56; k++) {
            this.SeedArray[k] -= this.SeedArray[1 + (k + 30) % 55];
            if (this.SeedArray[k] < 0) {
                this.SeedArray[k] += 2147483647;
            }
        }
    }
    this.inext = 0;
    this.inextp = 21;
    Seed = 1;
}
Random.prototype.milliseconds = function () {
    var str = new Date().valueOf().toString();
    return parseInt(str.substr(str.length - 6));
};
Random.prototype.InternalSample = function () {
    var num = this.inext;
    var num2 = this.inextp;
    if (++num >= 56) {
        num = 1;
    }
    if (++num2 >= 56) {
        num2 = 1;
    }
    var num3 = this.SeedArray[num] - this.SeedArray[num2];
    if (num3 == 2147483647) {
        num3--;
    }
    if (num3 < 0) {
        num3 += 2147483647;
    }
    this.SeedArray[num] = num3;
    this.inext = num;
    this.inextp = num2;
    return num3;
};
Random.prototype.Sample = function () {
    return this.InternalSample() * 4.6566128752457969E-10;
};
Random.prototype.GetSampleForLargeRange = function () {
    var num = this.InternalSample();
    var flag = this.InternalSample() % 2 == 0;
    if (flag) {
        num = -num;
    }
    var num2 = num;
    num2 += 2147483646.0;
    return num2 / 4294967293.0;
};
Random.prototype.Next = function (minValue, maxValue) {
    if (!minValue && !maxValue)
        return this.InternalSample();
    var num = maxValue - minValue;
    if (num <= 2147483647) {
        return parseInt((this.Sample() * num + minValue).toFixed(0));
    }
    return this.GetSampleForLargeRange() * num + minValue;
};
Random.prototype.NextDouble = function () {
    return this.Sample();
};
Random.prototype.NextBytes = function (buffer) {
    for (var i = 0; i < buffer.length; i++) {
        buffer[i] = this.InternalSample() % 256;
    }
};
return Random;
}());

ใช้:

        var r = new Random();
        var nextInt = r.Next(1, 100); //returns an integer between range
        var nextDbl = r.NextDouble(); //returns a random decimal

คลาส MS DotNet Random อยู่ภายใต้ใบอนุญาตMs-RSLซึ่งหมายความว่ามีลิขสิทธิ์ ดังนั้นควรใช้ความระมัดระวังเมื่อใช้รหัสปลอมนี้เนื่องจากอาจก่อให้เกิดกรณีการละเมิดลิขสิทธิ์
JohannesB

12

ใช้ฟังก์ชันนี้เพื่อรับตัวเลขสุ่มระหว่างช่วงที่กำหนด

function rnd(min,max){
    return Math.floor(Math.random()*(max-min+1)+min );
}

10

หลังจากสร้างหมายเลขสุ่มโดยใช้โปรแกรมคอมพิวเตอร์ก็ยังถือว่าเป็นหมายเลขสุ่มถ้าหมายเลขที่เลือกเป็นส่วนหนึ่งหรือเต็มหนึ่งของเริ่มต้น แต่หากมีการเปลี่ยนแปลงนักคณิตศาสตร์จะไม่ยอมรับว่าเป็นหมายเลขสุ่มและพวกเขาสามารถเรียกมันว่าเป็นหมายเลขที่มีอคติ แต่ถ้าคุณกำลังพัฒนาโปรแกรมสำหรับงานง่ายๆสิ่งนี้จะไม่เป็นสิ่งที่ควรพิจารณา แต่ถ้าคุณกำลังพัฒนาโปรแกรมเพื่อสร้างตัวเลขสุ่มสำหรับสิ่งที่มีค่าเช่นโปรแกรมลอตเตอรีหรือเกมการพนันโปรแกรมของคุณจะถูกปฏิเสธโดยผู้บริหารหากคุณไม่ได้พิจารณาเกี่ยวกับกรณีข้างต้น

ดังนั้นสำหรับคนประเภทนี้นี่คือคำแนะนำของฉัน:

สร้างหมายเลขสุ่มโดยใช้Math.random()(พูดแบบนี้n)

Now for [0,10) ==>  n*10 (i.e. one digit) and for[10,100) ==> n*100 (i.e. two digits) and so on. Here squire bracket indicates that boundary is inclusive and round bracket indicates boundary is exclusive.
Then remove the rest after the decimal point. (i.e. get floor) - using Math.floor(), this can be done.

หากคุณรู้วิธีอ่านตารางตัวเลขสุ่มเพื่อเลือกหมายเลขสุ่มคุณรู้ว่ากระบวนการข้างต้น (คูณด้วย 1, 10, 100 และต่อ ๆ ไป) จะไม่เป็นการละเมิดที่ฉันถูกกล่าวถึงในตอนเริ่มต้น (เพราะเปลี่ยนเฉพาะ ตำแหน่งของจุดทศนิยม)

ศึกษาตัวอย่างต่อไปนี้และพัฒนาตามความต้องการของคุณ

หากคุณต้องการตัวอย่าง [0,9] ดังนั้นชั้นของ n * 10 คือคำตอบของคุณและถ้าต้องการ [0,99] ดังนั้นชั้นของ n * 100 คือคำตอบของคุณเป็นต้น

ตอนนี้ให้เข้าสู่บทบาทของคุณ:

คุณถามตัวเลขในช่วงที่กำหนด (ในกรณีนี้คุณมีอคติในช่วงนั้น - จากการเอาตัวเลขจาก [1,6] โดยการหมุนตายแล้วคุณจะเอนเอียงไปที่ [1,6] แต่ก็ยังเป็นการสุ่มถ้าหากความตายไม่เอนเอียง .)

ดังนั้นให้พิจารณาช่วงของคุณ ==> [78, 247] จำนวนองค์ประกอบของช่วง = 247 - 78 + 1 = 170; (เนื่องจากขอบเขตทั้งสองรวมอยู่ด้วย

/*Mthod 1:*/
    var i = 78, j = 247, k = 170, a = [], b = [], c, d, e, f, l = 0;
    for(; i <= j; i++){ a.push(i); }
    while(l < 170){
        c = Math.random()*100; c = Math.floor(c);
        d = Math.random()*100; d = Math.floor(d);
        b.push(a[c]); e = c + d;
        if((b.length != k) && (e < k)){  b.push(a[e]); }
        l = b.length;
    }
    console.log('Method 1:');
    console.log(b);
/*Method 2:*/

    var a, b, c, d = [], l = 0;
    while(l < 170){
        a = Math.random()*100; a = Math.floor(a);
        b = Math.random()*100; b = Math.floor(b);
        c = a + b;
        if(c <= 247 || c >= 78){ d.push(c); }else{ d.push(a); }
        l = d.length;
    }
    console.log('Method 2:');
    console.log(d);

หมายเหตุ: ในวิธีที่หนึ่งก่อนอื่นฉันจะสร้างอาร์เรย์ซึ่งมีตัวเลขที่คุณต้องการจากนั้นจึงสุ่มไปยังอาร์เรย์อื่น ในวิธีที่สองสร้างตัวเลขแบบสุ่มและตรวจสอบว่าอยู่ในช่วงที่คุณต้องการ จากนั้นใส่มันลงในอาร์เรย์ ที่นี่ฉันสร้างตัวเลขสุ่มสองตัวและใช้ผลรวมของพวกเขาเพื่อเพิ่มความเร็วของโปรแกรมโดยลดอัตราความล้มเหลวที่จะได้รับหมายเลขที่มีประโยชน์ อย่างไรก็ตามการเพิ่มจำนวนที่สร้างขึ้นก็จะทำให้บางสิ่งบางอย่าง biassness ดังนั้นฉันขอแนะนำวิธีแรกของฉันในการสร้างตัวเลขสุ่มภายในช่วงที่กำหนด

ในทั้งสองวิธีคอนโซลของคุณจะแสดงผลลัพธ์ (กด f12 ใน Chrome เพื่อเปิดคอนโซล)


3
"สุ่ม" ไม่ได้แปลว่า "กระจายอย่างสม่ำเสมอ" "เอนเอียง" ไม่ได้แปลว่า "ไม่สุ่ม" สุ่มหมายถึงมาจากการแจกแจงความน่าจะเป็น
syzygy

6
แทบจะไม่สามารถบอกได้ว่าคำตอบนี้พยายามจะพูดอะไร อย่างไรก็ตามหากคุณต้องการตัวเลขสุ่มสำหรับการใช้งานเช่นหมายเลขลอตเตอรี่และการพนัน ก่อนอื่นคุณไม่ควรสร้างมันบนไคลเอนต์ ประการที่สองคุณต้องใช้ตัวสร้างตัวเลขสุ่มแบบเข้ารหัสที่ปลอดภัยและอัลโกที่ให้มานั้นไม่เพียงพอ การโทรสุ่มซ้ำ ๆ จะไม่ทำให้ผลลัพธ์ "สุ่มมากขึ้น" ผู้เขียนดูเหมือนจะกังวลเกี่ยวกับความเอนเอียง แต่ไม่ได้ให้อัลโก้ที่ดีสำหรับการป้องกัน ในความเป็นจริงคำตอบสั้น ๆ อื่น ๆ ที่สร้างตัวเลขสุ่มแบบไม่เอนเอียง
Jeff Walker Code Ranger

@JeffWalkerCodeRanger ฉันคิดว่าสิ่งที่เขาหมายถึงคือด้วยอัลกอริทึม "ปกติ" [เช่นMath.floor(Math.random() * (6 - 1 + 1) + 1)] หมายเลข 1 และ 6 จะต้องถูกหมุนน้อยกว่า 2, 3, 4 และ 5 อย่างไรก็ตามความแตกต่างนั้นไม่มีนัยสำคัญ
oldboy

10

สำหรับจำนวนเต็มแบบสุ่มที่มีช่วงลอง:

function random(minimum, maximum) {
  var bool = true;

  while (bool) {
    var number = (Math.floor(Math.random() * maximum + 1) + minimum);
    if (number > 20) {
      bool = true;
    } else {
      bool = false;
    }
  }

  return number;
}

8
function getRandomInt(lower, upper)
{
    //to create an even sample distribution
    return Math.floor(lower + (Math.random() * (upper - lower + 1)));

    //to produce an uneven sample distribution
    //return Math.round(lower + (Math.random() * (upper - lower)));

    //to exclude the max value from the possible values
    //return Math.floor(lower + (Math.random() * (upper - lower)));
}

ในการทดสอบฟังก์ชั่นนี้และรูปแบบของฟังก์ชั่นนี้ให้บันทึก HTML / JavaScript ด้านล่างลงในไฟล์และเปิดด้วยเบราว์เซอร์ รหัสจะสร้างกราฟที่แสดงการกระจายของการเรียกฟังก์ชันหนึ่งล้าน รหัสจะบันทึกกรณีขอบดังนั้นหากฟังก์ชันสร้างค่ามากกว่าค่าสูงสุดหรือน้อยกว่าค่าขั้นต่ำคุณจะต้อง. you.will.know.about.it

<html>
    <head>
        <script type="text/javascript">
        function getRandomInt(lower, upper)
        {
            //to create an even sample distribution
            return Math.floor(lower + (Math.random() * (upper - lower + 1)));

            //to produce an uneven sample distribution
            //return Math.round(lower + (Math.random() * (upper - lower)));

            //to exclude the max value from the possible values
            //return Math.floor(lower + (Math.random() * (upper - lower)));
        }

        var min = -5;
        var max = 5;

        var array = new Array();

        for(var i = 0; i <= (max - min) + 2; i++) {
          array.push(0);
        }

        for(var i = 0; i < 1000000; i++) {
            var random = getRandomInt(min, max);
            array[random - min + 1]++;
        }

        var maxSample = 0;
        for(var i = 0; i < max - min; i++) {
            maxSample = Math.max(maxSample, array[i]);
        }

        //create a bar graph to show the sample distribution
        var maxHeight = 500;
        for(var i = 0; i <= (max - min) + 2; i++) {
            var sampleHeight = (array[i]/maxSample) * maxHeight;

            document.write('<span style="display:inline-block;color:'+(sampleHeight == 0 ? 'black' : 'white')+';background-color:black;height:'+sampleHeight+'px">&nbsp;[' + (i + min - 1) + ']:&nbsp;'+array[i]+'</span>&nbsp;&nbsp;');
        }
        document.write('<hr/>');
        </script>
    </head>
    <body>

    </body>
</html>

7

ในการรับตัวเลขสุ่มพูดระหว่าง 1 ถึง 6 ให้ทำก่อน:

    0.5 + (Math.random() * ((6 - 1) + 1))

นี่จะคูณจำนวนสุ่มด้วย 6 แล้วบวก 0.5 เข้าไป ปัดเศษตัวเลขเป็นจำนวนเต็มบวกโดยทำ:

    Math.round(0.5 + (Math.random() * ((6 - 1) + 1))

ปัดเศษตัวเลขเป็นจำนวนเต็มที่ใกล้เคียงที่สุด

หรือเพื่อให้เข้าใจได้มากขึ้นให้ทำสิ่งนี้:

    var value = 0.5 + (Math.random() * ((6 - 1) + 1))
    var roll = Math.round(value);
    return roll;

โดยทั่วไปรหัสสำหรับการทำเช่นนี้โดยใช้ตัวแปรคือ:

    var value = (Min - 0.5) + (Math.random() * ((Max - Min) + 1))
    var roll = Math.round(value);
    return roll;

เหตุผลที่นำค่า 0.5 จากค่าต่ำสุดมาใช้เพราะการใช้ค่าขั้นต่ำเพียงอย่างเดียวจะช่วยให้คุณได้รับจำนวนเต็มที่มากกว่าหนึ่งค่าสูงสุดของคุณ ด้วยการละ 0.5 จากค่าต่ำสุดคุณจะป้องกันไม่ให้ค่าสูงสุดถูกปัดเศษ

หวังว่าจะช่วย


สมเหตุสมผลถ้าคุณไม่รวม0ดังนั้นไม่จำเป็นต้อง "ปัดเศษ" ช่วงจาก 0 ถึง 0.5
ILMostro_7

7

การใช้รหัสต่อไปนี้คุณสามารถสร้างอาร์เรย์ของตัวเลขสุ่มโดยไม่ต้องทำซ้ำในช่วงที่กำหนด

function genRandomNumber(how_many_number,min,max) {

            // parameters
            // how_many_number : how many numbers you want to generate. For example it is 5.
            // min(inclusive) : minimum/low value of a range. it must be any positive integer but less than max. i.e 4
            // max(inclusive) : maximun value of a range. it must be any positive integer. i.e 50
            // return type: array

            var random_number = [];
            for (var i = 0; i < how_many_number; i++) {
                var gen_num = parseInt((Math.random() * (max-min+1)) + min);
                do {
                    var is_exist = random_number.indexOf(gen_num);
                    if (is_exist >= 0) {
                        gen_num = parseInt((Math.random() * (max-min+1)) + min);
                    }
                    else {
                        random_number.push(gen_num);
                        is_exist = -2;
                    }
                }
                while (is_exist > -1);
            }
            document.getElementById('box').innerHTML = random_number;
        }

7

ฉันรู้ว่าคำถามนี้ได้รับคำตอบแล้ว แต่คำตอบของฉันสามารถช่วยใครบางคน

ฉันพบวิธีการง่าย ๆ ใน W3Schools:

Math.floor((Math.random() * max) + min);

หวังว่านี่จะช่วยใครซักคน


1
Math.floor ((Math.random () * 1) + 0); ให้ 0 เสมอ
madprops

1
@madprops เนื่องจากจำนวนสูงสุดเป็นเอกสิทธิ์ ในการรับ 0 หรือ 1 คุณควรตั้งค่า 2 เป็นจำนวนสูงสุด
NutCracker

1
หรือคุณเพียงแค่บวก + 1 ในฟังก์ชั่นที่เรียกเมธอดนี้
Pietro Coelho

6

สุ่มจำนวนเต็มระหว่างต่ำสุดและสูงสุด:

function randomRange(l,h){
  var range = (h-l);
  var random = Math.floor(Math.random()*range);
  if (random === 0){random+=1;}
  return l+random;
}

ไม่ใช่ทางออกที่หรูหราที่สุด .. แต่มีบางอย่างที่รวดเร็ว


5

นี่คือสิ่งที่ฉันใช้ในการสร้างตัวเลขสุ่ม

function random(high,low) {
    high++;
    return Math.floor((Math.random())*(high-low))+low;
}

เราดำเนินการhigh++เพราะMath.random()สร้างตัวเลขสุ่มระหว่าง 0, (รวม) และ 1 (ไม่รวม) คนที่ถูกยกเว้นหมายความว่าเราจะต้องเพิ่มความสูงโดยหนึ่งก่อนที่จะดำเนินการทางคณิตศาสตร์ใด ๆ จากนั้นเราก็ลบค่าต่ำจากระดับสูงให้จำนวนสูงสุดในการสร้าง - ต่ำจากนั้น + ต่ำนำค่าสูงกลับมาเป็นปกติและทำให้ตัวเลขต่ำสุดต่ำที่สุด จากนั้นเราส่งคืนหมายเลขผลลัพธ์

random(7,3) สามารถกลับมา 3,4,5,6, or 7


2
เช่นhighเดียวกับที่ใช้เพียงครั้งเดียวคุณอาจใช้high-low+1แทนที่จะมีคำสั่งเพิ่มแยกต่างหาก นอกจากนี้ผู้ใช้ส่วนใหญ่คาดหวังว่าlowพารามิเตอร์จะมาก่อน
Chris Walsh

4
    <!DOCTYPE html>
<html>
    <head>
            <meta charset="utf-8" />
    </head>
    <body>
        <script>
            /*

                assuming that window.crypto.getRandomValues is available
                the real range would be fron 0 to 1,998 instead of 0 to 2,000
                See javascript documentation for explanation
                https://developer.mozilla.org/en-US/docs/Web/API/RandomSource/getRandomValues
            */
            var array = new Uint8Array(2);
            window.crypto.getRandomValues(array);
            console.log(array[0] + array[1]);

        </script>
    </body>
</html>

Uint8Array สร้างอาร์เรย์ที่เต็มไปด้วยตัวเลขสูงสุด 3 หลักซึ่งจะเป็นสูงสุด 999 รหัสนี้สั้นมาก


4

นี่คือตัวอย่างของฟังก์ชั่นจาวาสคริปต์ที่สามารถสร้างจำนวนสุ่มของความยาวที่ระบุใด ๆโดยไม่ต้องใช้ Math.random ():

    function genRandom(length)
    {
     const t1 = new Date().getMilliseconds();
     var min = "1",max = "9";
     var result;
     var numLength = length;
     if (numLength != 0)
     {
        for (var i = 1; i < numLength; i++)
        {
           min = min.toString() + "0";
           max = max.toString() + "9";
        }
     } 
     else
     {
        min = 0;
        max = 0;
        return; 
     }

      for (var i = min; i <= max; i++)
      {
           //Empty Loop
      }

      const t2 = new Date().getMilliseconds();
      console.log(t2);
      result = ((max - min)*t1)/t2;
      console.log(result);
      return result;
    }

t1 / t2 ใกล้เคียงกับ 1 เสมอและฟังก์ชันของคุณจะส่งกลับหมายเลขเดียวกันเมื่อฟังก์ชันถูกเรียกซ้ำ ๆ .. jsbin.com/xogufacera/edit?js,console
Sunil BN

ตรวจสอบ jsbin url .. คุณจะเห็นผลลัพธ์ด้วยตัวคุณเอง
Sunil BN

มันใช้งานได้ดีเมื่อความยาวอยู่ระหว่าง 4-10 (อย่างที่ฉันทดสอบบนเครื่อง) เพราะค่าคงที่ T1 & T2 ควรมีระยะทางที่เหมาะสม
Nilesh Pawar

3

นี่คือการสุ่มตัวเลขในช่วงเนื่องจากฉันต้องการรับตัวเลขสุ่มภายในช่วงของเลขฐานเป็นเลขชี้กำลัง เช่น base = 10, exponent = 2, ให้ตัวเลขสุ่มตั้งแต่ 0 ถึง 100, เป็นการดีเลิศและอื่น ๆ

ถ้ามันช่วยใช้มันนี่คือ:

// get random number within provided base + exponent
// by Goran Biljetina --> 2012

function isEmpty(value){
    return (typeof value === "undefined" || value === null);
}
var numSeq = new Array();
function add(num,seq){
    var toAdd = new Object();
     toAdd.num = num;
     toAdd.seq = seq;
     numSeq[numSeq.length] = toAdd;
}
function fillNumSeq (num,seq){
    var n;
    for(i=0;i<=seq;i++){
        n = Math.pow(num,i);
        add(n,i);
    }
}
function getRandNum(base,exp){
    if (isEmpty(base)){
        console.log("Specify value for base parameter");
    }
    if (isEmpty(exp)){
        console.log("Specify value for exponent parameter");
    }
    fillNumSeq(base,exp);
    var emax;
    var eseq;
    var nseed;
    var nspan;
    emax = (numSeq.length);
    eseq = Math.floor(Math.random()*emax)+1;
    nseed = numSeq[eseq].num;
    nspan = Math.floor((Math.random())*(Math.random()*nseed))+1;
    return Math.floor(Math.random()*nspan)+1;
}

console.log(getRandNum(10,20),numSeq);
//testing:
//getRandNum(-10,20);
//console.log(getRandNum(-10,20),numSeq);
//console.log(numSeq);

3

Math.random() รวดเร็วและเหมาะสำหรับวัตถุประสงค์หลายอย่าง แต่มันไม่เหมาะสมถ้าคุณต้องการค่าที่ปลอดภัยแบบเข้ารหัส (ไม่ปลอดภัย) หรือถ้าคุณต้องการจำนวนเต็มจากการกระจายแบบไม่เอนเอียงที่สมบูรณ์แบบเหมือนกัน (วิธีการคูณที่ใช้ในคำตอบอื่น ๆ กว่าคนอื่น ๆ )

ในกรณีเช่นนี้เราสามารถใช้crypto.getRandomValues()เพื่อสร้างจำนวนเต็มที่ปลอดภัยและปฏิเสธค่าใด ๆ ที่สร้างขึ้นซึ่งเราไม่สามารถแมปอย่างสม่ำเสมอในช่วงเป้าหมาย สิ่งนี้จะช้าลง แต่ไม่ควรมีนัยสำคัญหากคุณไม่ได้สร้างคุณค่าจำนวนมาก

ในการชี้แจงข้อกังวลเกี่ยวกับการแจกแจงแบบเอนเอียงให้พิจารณากรณีที่เราต้องการสร้างค่าระหว่าง 1 ถึง 5 แต่เรามีตัวสร้างตัวเลขสุ่มที่สร้างค่าระหว่าง 1 ถึง 16 (ค่า 4 บิต) เราต้องการให้มีการแมปค่าที่สร้างขึ้นจำนวนเท่ากันกับแต่ละค่าเอาต์พุต แต่ 16 ไม่ได้แบ่งเท่า ๆ กัน 5: มันเหลือเศษ 1 ดังนั้นเราจำเป็นต้องปฏิเสธ 1 ค่าที่สร้างขึ้นได้และต่อเมื่อเราได้รับเท่านั้น หนึ่งใน 15 ค่าที่น้อยกว่าซึ่งสามารถแมปอย่างสม่ำเสมอในช่วงเป้าหมายของเรา พฤติกรรมของเราอาจมีลักษณะเหมือนรหัสเทียมนี้:

Generate a 4-bit integer in the range 1-16.
If we generated  1,  6, or 11 then output 1.
If we generated  2,  7, or 12 then output 2.
If we generated  3,  8, or 13 then output 3.
If we generated  4,  9, or 14 then output 4.
If we generated  5, 10, or 15 then output 5.
If we generated 16 then reject it and try again.

รหัสต่อไปนี้ใช้ตรรกะที่คล้ายกัน แต่สร้างจำนวนเต็ม 32 บิตแทนเพราะนั่นเป็นขนาดจำนวนเต็มทั่วไปที่ใหญ่ที่สุดที่สามารถแสดงด้วยnumberชนิดมาตรฐานของ JavaScript (สิ่งนี้สามารถแก้ไขเพื่อใช้BigInts หากคุณต้องการช่วงที่ใหญ่กว่า) โดยไม่คำนึงถึงช่วงที่เลือกเศษส่วนของค่าที่สร้างขึ้นที่ถูกปฏิเสธจะน้อยกว่า 0.5 เสมอดังนั้นจำนวนการปฏิเสธที่คาดหวังจะน้อยกว่า 1.0 และ มักจะใกล้กับ 0.0; คุณไม่จำเป็นต้องกังวลเกี่ยวกับมันวนซ้ำตลอดไป

const randomInteger = (min, max) => {
  const range = max - min;
  const maxGeneratedValue = 0xFFFFFFFF;
  const possibleResultValues = range + 1;
  const possibleGeneratedValues = maxGeneratedValue + 1;
  const remainder = possibleGeneratedValues % possibleResultValues;
  const maxUnbiased = maxGeneratedValue - remainder;

  if (!Number.isInteger(min) || !Number.isInteger(max) ||
       max > Number.MAX_SAFE_INTEGER || min < Number.MIN_SAFE_INTEGER) {
    throw new Error('Arguments must be safe integers.');
  } else if (range > maxGeneratedValue) {
    throw new Error(`Range of ${range} (from ${min} to ${max}) > ${maxGeneratedValue}.`);
  } else if (max < min) {
    throw new Error(`max (${max}) must be >= min (${min}).`);
  } else if (min === max) {
    return min;
  } 

  let generated;
  do {
    generated = crypto.getRandomValues(new Uint32Array(1))[0];
  } while (generated > maxUnbiased);

  return min + (generated % possibleResultValues);
};

console.log(randomInteger(-8, 8));          // -2
console.log(randomInteger(0, 0));           // 0
console.log(randomInteger(0, 0xFFFFFFFF));  // 944450079
console.log(randomInteger(-1, 0xFFFFFFFF));
// Error: Range of 4294967296 covering -1 to 4294967295 is > 4294967295.
console.log(new Array(12).fill().map(n => randomInteger(8, 12)));
// [11, 8, 8, 11, 10, 8, 8, 12, 12, 12, 9, 9]


3

การเข้ารหัสลับที่แข็งแกร่ง

หากต้องการรับจำนวนเต็มแบบสุ่มที่เข้ารหัสลับได้ใน ragne [x, y] ให้ลอง

let cs= (x,y)=>x+(y-x+1)*crypto.getRandomValues(new Uint32Array(1))[0]/2**32|0

console.log(cs(4,8))


4
อันนี้น่าทึ่ง
Akin Hwan

1

คุณสามารถโค้ดขนาดสั้นนี้ได้ไหม

let randomNumber = function(first,second){
let number = Math.floor(Math.random()*Math.floor(second));
while(number<first){

    number = Math.floor(Math.random()*Math.floor(second));
}
return number;
}

1
มีบรรทัดซ้ำที่ไม่จำเป็นที่นี่ เพียงใช้do - whileแทนwhile
Javi Marzán

1

Ionuț G. Stanเขียนคำตอบที่ยอดเยี่ยม แต่มันซับซ้อนเกินไปสำหรับฉันที่จะเข้าใจ ดังนั้นฉันจึงพบคำอธิบายที่ง่ายขึ้นของแนวคิดเดียวกันที่https://teamtreehouse.com/community/mathfloor-mathrandom-max-min-1min-explanationโดย Jason Anello

หมายเหตุ:สิ่งสำคัญเดียวที่คุณควรรู้ก่อนอ่านคำอธิบายของ Jason คือคำจำกัดความของ "ตัด" Math.floor()เขาใช้คำว่าเมื่ออธิบาย พจนานุกรม Oxford กำหนด "truncate" เป็น:

ร่น (บางสิ่ง) โดยการตัดส่วนบนหรือส่วนท้าย


0

สิ่งนี้สามารถจัดการกับการสร้างตัวเลขสุ่มได้ไม่เกิน 20 หลัก

JS

var generatedNumbers = [];

function generateRandomNumber(precision) { // precision --> number precision in integer 
    if (precision <= 20) {
        var randomNum = Math.round(Math.random().toFixed(precision) * Math.pow(10, precision));
        if (generatedNumbers.indexOf(randomNum) > -1) {
            if (generatedNumbers.length == Math.pow(10, precision))
                return "Generated all values with this precision";
                return generateRandomNumber(precision);
        } else {
            generatedNumbers.push(randomNum);
            return randomNum;
        }
    } else
       return "Number Precision shoould not exceed 20";
}
generateRandomNumber(1);

ป้อนคำอธิบายรูปภาพที่นี่

JsFiddle


ฉัน upvoting นี้เพียงเพราะ
Taylor Ackley

1
@TaylorAckley คำตอบนี้ไม่ได้ตอบคำถาม
RomainValeri

0

/ * เขียนฟังก์ชั่นที่เรียกrandUpToว่ารับหมายเลขและส่งกลับจำนวนเต็มแบบสุ่มระหว่าง 0 ถึงหมายเลขนั้น? * /

var randUpTo = function(num) {
    return Math.floor(Math.random() * (num - 1) + 0);
};

/ * เขียนฟังก์ชั่นที่เรียกrandBetweenว่ายอมรับตัวเลขสองตัวที่แทนช่วงและส่งกลับจำนวนเต็มแบบสุ่มระหว่างตัวเลขทั้งสอง * /

var randBetween = function (min, max) {
    return Math.floor(Math.random() * (max - min - 1)) + min;
};

/ * เขียนฟังก์ชั่นที่เรียกrandFromTillว่ายอมรับตัวเลขสองตัวที่แทนช่วงและส่งกลับตัวเลขสุ่มระหว่าง min (รวม) และ max (พิเศษ) * /

var randFromTill = function (min, max) {
    return Math.random() * (max - min) + min;
};

/ * เขียนฟังก์ชั่นที่เรียกrandFromToว่ารับตัวเลขสองตัวที่เป็นตัวแทนของช่วงและส่งกลับจำนวนเต็มแบบสุ่มระหว่าง min (รวม) และ max (รวม) * /

var randFromTo = function (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
};

1
ที่สวยงามคุณสามารถทราบได้ว่าแรนด์ระหว่าง (พิเศษ) (พิเศษ)?
pfdint

0

ฉันสร้างฟังก์ชันนี้ซึ่งคำนึงถึงตัวเลือกบัญชีเช่น min, max, แยก (รายการของ ints ที่จะแยก) และ seed (ในกรณีที่คุณต้องการตัวสร้างแบบสุ่ม seeded)

get_random_int = function(args={})
{
    let def_args =
    {
        min: 0,
        max: 1,
        exclude: false,
        seed: Math.random
    }

    args = Object.assign(def_args, args)

    let num = Math.floor(args.seed() * (args.max - args.min + 1) + args.min)

    if(args.exclude)
    {
        let diff = args.max - args.min
        let n = num

        for(let i=0; i<diff*2; i++)
        {
            if(args.exclude.includes(n))
            {
                if(n + 1 <= args.max)
                {
                    n += 1
                }

                else
                {
                    n = args.min
                }
            }

            else
            {
                num = n
                break
            }
        }
    }

    return num
}

มันสามารถใช้เช่น:

let n = get_random_int
(
    {
        min: 0,
        max: some_list.length - 1,
        exclude: [3, 6, 5],
        seed: my_seed_function
    }
)

หรือมากกว่านั้น:

let n = get_random_int
(
    {
        min: 0,
        max: some_list.length - 1
    }
)

จากนั้นคุณสามารถทำได้:

let item = some_list[n]

สรุปสาระสำคัญ: https://gist.github.com/madprops/757deb000bdec25776d5036dae58ee6e


0
  • สุ่ม (นาที, สูงสุด) สร้างตัวเลขสุ่มระหว่างขั้นต่ำ (รวม) และสูงสุด (พิเศษ)
  • Math.floor ปัดเศษตัวเลขลงให้เป็นจำนวนเต็มที่ใกล้เคียงที่สุด

    function generateRandomInteger (min, max) { 
        return Math.floor(random(min,max)) 
    }`

ดังนั้นหากต้องการสร้างจำนวนเต็มแบบสุ่มระหว่าง 4 ถึง 8 ให้เรียกฟังก์ชันข้างต้นด้วยอาร์กิวเมนต์ดังนี้

generateRandomInteger (4,9)

0

วิธีสร้างหมายเลขสุ่มระหว่าง 0 ถึง n ของฉันโดยที่ n <= 10 (ไม่รวม n):

Math.floor((Math.random() * 10) % n)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.