สร้างสตริง / ตัวอักษรแบบสุ่มใน JavaScript


1780

ฉันต้องการสตริง 5 [a-zA-Z0-9]ตัวอักษรประกอบด้วยตัวอักษรสุ่มเลือกจากชุดที่

วิธีที่ดีที่สุดในการทำเช่นนี้กับ JavaScript คืออะไร?


48
คำเตือน: ไม่มีคำตอบใดที่มีtrue-randomผล! pseudo-randomพวกเขาเป็นเพียง เมื่อใช้สตริงสุ่มสำหรับการป้องกันหรือรักษาความปลอดภัยอย่าใช้สายเหล่านี้ !!! ลองใช้หนึ่งใน api เหล่านี้: random.org
Ron van der Heijden

48
Math.random (). toString (36) .replace (/ [^ az] + / g, '')
Muaz Khan

13
กรุณาใส่วิธีการแก้ปัญหา
chryss

216
Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
ฟรีดริช

12
หมายเหตุHTML5 webcrypto randomness APIให้การสุ่มอย่างแท้จริง
mikemaccana

คำตอบ:


2430

ฉันคิดว่าสิ่งนี้จะได้ผลสำหรับคุณ:

function makeid(length) {
   var result           = '';
   var characters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
   var charactersLength = characters.length;
   for ( var i = 0; i < length; i++ ) {
      result += characters.charAt(Math.floor(Math.random() * charactersLength));
   }
   return result;
}

console.log(makeid(5));


117
นี่เป็นเรื่องปกติสำหรับสตริงสั้น ๆ แต่ระวังการใช้+=กับสตริงเช่นนี้ทำให้เกิดพฤติกรรม O (n ^ 2) หากคุณต้องการสร้างสตริงที่ยาวขึ้นคุณควรสร้างอาร์เรย์ของอักขระแต่ละตัวและรวมเข้าด้วยกันในตอนท้าย
dan_waterworth

97
@dan_waterworth มันอาจจะไม่สำคัญในเกือบทุกกรณี: codinghorror.com/blog/2009/01/…
Alex Reece

7
@dan_waterworth ที่จริงแล้ว+=มักจะเร็วกว่าด้วยเหตุผลบางอย่างแม้แต่ใช้ในลูป - jsperf.com/join-vs-concatenation
Konrad Borowski

18
@JonathanPaulson แสดงตัวเลขที่ ดูความคิดเห็นก่อนหน้านี้ที่มีลิงก์jsperfหรือjsperf.com/sad-tragedy-of-microoptimizationหรือsitepen.com/blog/2008/05/09/string-performance-an-analysis คำถามอื่น ๆ นอกจากนี้คำถามนี้มีเพียง 5 concatenations .
Alex Reece

11
@codenamejames โปรดอย่าใช้สิ่งนี้ในการใส่เกลือรหัสผ่านของคุณ มันเป็นเพียงการสุ่มหลอกไม่ปลอดภัย สมมติว่าคุณกำลังใช้ Node (ฉันไม่แน่ใจด้วยซ้ำว่าจะเริ่มต้นที่ใดถ้าคุณขายเกลือที่ฝั่งไคลเอ็นต์) ให้ใช้cryptoแทน
Hydrothermal

2330

let r = Math.random().toString(36).substring(7);
console.log("random", r);

หมายเหตุ: อัลกอริทึมด้านบนมีจุดอ่อนดังต่อไปนี้:

  • มันจะสร้างที่ใดก็ได้ระหว่าง 0 และ 6 ตัวอักษรเนื่องจากความจริงที่ว่าศูนย์ต่อท้ายจะถูกลบออกเมื่อ stringifying จุดลอย
  • มันขึ้นอยู่กับอัลกอริทึมที่ใช้เพื่อทำให้ตัวเลขจุดลอยตัวเป็นจำนวนมากซึ่งมีความซับซ้อนอย่างน่ากลัว (ดูกระดาษ"วิธีพิมพ์ตัวเลขทศนิยมอย่างถูกต้อง" )
  • Math.random()อาจสร้างผลลัพธ์ที่คาดการณ์ได้ ("ดูสุ่ม" แต่ไม่สุ่มจริง ๆ ) ขึ้นอยู่กับการใช้งาน สายอักขระผลลัพธ์ไม่เหมาะสมเมื่อคุณต้องการรับประกันความเป็นเอกลักษณ์หรือความคาดเดาไม่ได้
  • แม้ว่าจะผลิต 6 สุ่มสม่ำเสมออักขระคาดเดาไม่ได้คุณสามารถคาดหวังที่จะเห็นการซ้ำหลังจากการสร้างเพียงประมาณ 50,000 สตริงเนื่องจากความขัดแย้งวันเกิด (sqrt (36 ^ 6) = 46656)

276
Math.random().toString(36).substr(2, 5)เนื่องจาก.substring(7)ทำให้มีความยาวเกิน 5 อักขระ คะแนนเต็มยัง!
dragon

81
@Scoop toStringวิธีการของประเภทตัวเลขในจาวาสคริปต์ใช้พารามิเตอร์ตัวเลือกในการแปลงตัวเลขเป็นฐานที่กำหนด ตัวอย่างเช่นถ้าคุณผ่านสองตัวอย่างคุณจะเห็นหมายเลขของคุณแสดงเป็นเลขฐานสอง เช่นเดียวกับฐานสิบหก (ฐาน 16) ฐานหก 36 ใช้ตัวอักษรเพื่อแทนตัวเลขที่เกิน 9 ด้วยการแปลงตัวเลขสุ่มเป็นฐาน 36 คุณจะจบลงด้วยการสุ่มตัวอักษรและตัวเลข
Chris Baker

76
ดูสวยงาม แต่ในบางกรณีก็สร้างสตริงว่าง! หากการสุ่มส่งกลับค่า 0, 0.5, 0.25, 0.125 ... จะทำให้สตริงว่างหรือสั้น
gertas

67
@gertas สิ่งนี้สามารถหลีกเลี่ยงได้โดย(Math.random() + 1).toString(36).substring(7);
George Reith

84
Guy นี่ไร้ประโยชน์จริง เรียกใช้เพียง 1000000 ครั้งและโดยทั่วไปคุณจะเกิดเหตุการณ์ซ้ำประมาณ 110000 ครั้ง: var values ​​= {}, i = 0, ซ้ำกันจำนวน = 0, val; ในขณะที่ (ฉัน <1000000) {val = Math.random (). toString (36) .substring (7); ถ้า (ค่า [val]) {ซ้ำกันเคานต์ ++; } values ​​[val] = 1; ฉัน ++; } console.log ("DUPLICATES รวม" ซ้ำซ้อนนับ);
hacklikecrack

463

คณิตศาสตร์แบบสุ่มไม่ดีสำหรับสิ่งนี้

ตัวเลือกที่ 1

หากคุณสามารถทำเซิร์ฟเวอร์นี้ได้เพียงใช้โมดูลcrypto

var crypto = require("crypto");
var id = crypto.randomBytes(20).toString('hex');

// "bb5dc8842ca31d4603d6aa11448d1654"

สตริงผลลัพธ์จะยาวเป็นสองเท่าของไบต์สุ่มที่คุณสร้าง แต่ละไบต์ที่เข้ารหัสถึงฐานสิบหกคือ 2 อักขระ 20 ไบต์จะเป็นอักขระฐานสิบหก 40 ตัว


ตัวเลือก 2

หากคุณต้องทำไคลเอนต์นี้ด้านอาจลองโมดูล uuid -

var uuid = require("uuid");
var id = uuid.v4();

// "110ec58a-a0f2-4ac4-8393-c866d813b8d1"

ตัวเลือก 3

หากคุณต้องทำไคลเอ็นต์นี้ - และคุณไม่ต้องสนับสนุนเบราว์เซอร์เก่าคุณสามารถทำได้โดยไม่ต้องพึ่งพา -

// dec2hex :: Integer -> String
// i.e. 0-255 -> '00'-'ff'
function dec2hex (dec) {
  return ('0' + dec.toString(16)).substr(-2)
}

// generateId :: Integer -> String
function generateId (len) {
  var arr = new Uint8Array((len || 40) / 2)
  window.crypto.getRandomValues(arr)
  return Array.from(arr, dec2hex).join('')
}

console.log(generateId())
// "82defcf324571e70b0521d79cce2bf3fffccd69"

console.log(generateId(20))
// "c1a050a4cd1556948d41"


สำหรับข้อมูลเพิ่มเติมเกี่ยวกับcrypto.getRandomValues-

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

นี่คือตัวอย่างของคอนโซลเล็กน้อย -

> var arr = new Uint8Array(4) # make array of 4 bytes (values 0-255)
> arr
Uint8Array(4) [ 0, 0, 0, 0 ]

> window.crypto
Crypto { subtle: SubtleCrypto }

> window.crypto.getRandomValues()
TypeError: Crypto.getRandomValues requires at least 1 argument, but only 0 were passed

> window.crypto.getRandomValues(arr)
Uint8Array(4) [ 235, 229, 94, 228 ]

สำหรับการรองรับ IE11 คุณสามารถใช้ -

(window.crypto || window.msCrypto).getRandomValues(arr)

สำหรับความครอบคลุมของเบราว์เซอร์โปรดดูที่https://caniuse.com/#feat=getrandomvalues


4
เผง ในขณะที่ UUID นั้นใช้ได้สำหรับการกำหนด ID ให้กับสิ่งต่าง ๆ การใช้มันเป็นสตริงของตัวอักษรแบบสุ่มนั้นไม่ใช่ความคิดที่ดีสำหรับเหตุผลนี้ (และเหตุผลอื่น ๆ )
wmassingham

2
ไม่จำเป็นต้องใช้.map()ในทางเลือกที่ 3 ===Array.from(arr, dec2hex).join('') Array.from(arr).map(dec2hex).join('')ขอขอบคุณที่แนะนำฉันให้รู้จักกับคุณสมบัติเหล่านี้ :-)
Fred Gandt

6
คุณควรพูดถึงในคำตอบที่ตัวเลือกที่ 2 ยังต้องการ node.js ในการทำงานมันไม่ได้เป็นจาวาสคริปต์ที่บริสุทธิ์
Esko

5
ในขณะที่มีความปลอดภัยมากขึ้นการเข้ารหัสลับนี้ไม่จริงตอบสนองความต้องการของคำถามเพราะมันออกเพียง 0-9 และ af (เลขฐานสิบหก) และไม่ใช่ 0-9, az, AZ
qJake

1
ไม่ได้เป็นrequireโมดูลเท่านั้นที่จะสามารถที่จะเป็นด้านเซิร์ฟเวอร์ที่ใช้?
aJetHorn

173

สั้นง่ายและเชื่อถือได้

ส่งคืนอักขระสุ่ม 5 ตัวตรงข้ามกับคำตอบที่ได้รับความนิยมสูงสุดที่นี่

Math.random().toString(36).substr(2, 5);

9
จะเกิดอะไรขึ้นถ้าMath.random().toString(36)ส่งคืนตัวเลขที่มีอักขระน้อยกว่า 5 ตัว
Michael Litvin

3
นั่นเป็นคำฟ้องที่น่าสนใจจาก @ Aperçuฉันไม่ได้บอกว่าฉันคิดค้นวิธีแก้ปัญหา แต่ฉันใช้มันในโครงการของฉันมาหลายปีแล้ว และไม่มีส่วนเกี่ยวข้องกับความคิดเห็นที่คุณพูดถึง และฉันค่อนข้างแน่ใจว่าดังนั้นสิ่งที่สำคัญคือข้อมูลที่มีประโยชน์ที่สุดในสถานที่ที่เหมาะสมและแม้ว่ามันจะมีอยู่แล้วในที่อื่นเช่นกัน โชคดีที่ดูเหมือนว่าอย่างน้อย 51 คนพบว่าคำตอบนี้มีประโยชน์ยินดีต้อนรับ!
Silver Ringvee

3
เพื่อหลีกเลี่ยงการรับสตริงที่ว่างเปล่าในกรณีที่ Math.random () ส่งคืนค่า 0 คุณสามารถใช้function getRandomString() { var result = ''; while (!result) result = Math.random().toString(36).substring(2); return result; };
mikep

5
@rinogo Math.random () สามารถส่งคืน 0 แต่ไม่ใช่ 1 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
......

6
ฉันรันโค้ดนี้ 1,000,000,000 ครั้งและยังไม่ได้รับสตริงว่าง: jsfiddle.net/mtp5730r ฉันจะบอกว่าคุณค่อนข้างปลอดภัยจากการรับสตริงว่างเปล่า
MacroMan

157

นี่คือการปรับปรุงในคำตอบที่ดีเยี่ยมของ doubletap ต้นฉบับมีข้อบกพร่องสองประการที่กล่าวถึงที่นี่:

อันดับแรกตามที่คนอื่น ๆ พูดถึงมันมีความเป็นไปได้น้อยมากที่จะสร้างสตริงสั้น ๆ หรือแม้แต่สตริงว่างเปล่า (ถ้าตัวเลขสุ่มเป็น 0) ซึ่งอาจทำให้แอปพลิเคชันของคุณเสียหาย นี่คือทางออก:

(Math.random().toString(36)+'00000000000000000').slice(2, N+2)

ประการที่สองทั้งต้นฉบับและโซลูชันด้านบน จำกัด ขนาดสตริง N ถึง 16 อักขระ ต่อไปนี้จะส่งคืนสตริงที่มีขนาด N สำหรับ N ใด ๆ (แต่โปรดทราบว่าการใช้ N> 16 จะไม่เพิ่มการสุ่มหรือลดความน่าจะเป็นของการชน):

Array(N+1).join((Math.random().toString(36)+'00000000000000000').slice(2, 18)).slice(0, N)

คำอธิบาย:

  1. เลือกตัวเลขสุ่มในช่วง [0,1) คือระหว่าง 0 (รวม) และ 1 (พิเศษ)
  2. แปลงตัวเลขเป็นสตริงฐาน -36 เช่นใช้อักขระ 0-9 และ az
  3. แผ่นที่มีศูนย์ (แก้ไขปัญหาแรก)
  4. ฝืนตัวผู้นำ '0. ' เลขนำหน้าและเลขศูนย์เสริมพิเศษ
  5. ทำซ้ำสตริงเพียงพอที่จะมีอย่างน้อย N ตัวอักษร (โดยการรวมสตริงว่างกับสตริงสุ่มที่สั้นกว่าที่ใช้เป็นตัวคั่น)
  6. แบ่งอักขระทั้งหมด N ตัวจากสตริง

ความคิดเพิ่มเติม:

  • วิธีการแก้ปัญหานี้ไม่ได้ใช้ตัวอักษรตัวพิมพ์ใหญ่ แต่ในเกือบทุกกรณี (ไม่มีการเล่นสำนวน) มันไม่สำคัญ
  • ความยาวสตริงสูงสุดที่ N = 16 ในคำตอบดั้งเดิมถูกวัดใน Chrome ใน Firefox มันคือ N = 11 แต่ตามที่อธิบายไว้วิธีที่สองคือเกี่ยวกับการสนับสนุนความยาวสตริงที่ร้องขอไม่เกี่ยวกับการเพิ่มการสุ่มดังนั้นจึงไม่ได้สร้างความแตกต่างมากนัก
  • สตริงที่ส่งคืนทั้งหมดมีความน่าจะเป็นเท่ากับที่จะถูกส่งคืนอย่างน้อยเท่าที่ผลลัพธ์ที่ส่งคืนโดย Math.random () มีการกระจายอย่างเท่าเทียมกัน (นี่ไม่ใช่การสุ่มแบบแรงเข้ารหัสลับในทุกกรณี)
  • อาจมีการส่งคืนสตริงที่มีขนาดเท่าที่เป็นไปไม่ได้ทั้งหมด ในการแก้ปัญหาที่สองนี้เห็นได้ชัด (เนื่องจากสตริงที่เล็กกว่าจะถูกทำซ้ำ) แต่ในคำตอบเดิมนี้เป็นจริงเนื่องจากในการแปลงเป็นฐาน 36 บิตไม่กี่บิตสุดท้ายอาจไม่ได้เป็นส่วนหนึ่งของบิตสุ่มดั้งเดิม หากคุณดูผลลัพธ์ของ Math.random (). toString (36) คุณจะสังเกตเห็นว่าอักขระตัวสุดท้ายไม่ได้รับการกระจายอย่างเท่าเทียมกัน อีกครั้งในเกือบทุกกรณีมันไม่สำคัญ แต่เราแบ่งสตริงสุดท้ายจากจุดเริ่มต้นมากกว่าจุดสิ้นสุดของสตริงสุ่มเพื่อไม่ให้สตริงสั้น (เช่น N = 1)

ปรับปรุง:

ต่อไปนี้เป็นรูปแบบการทำงานอื่น ๆ ที่ฉันใช้ด้วย พวกเขาแตกต่างจากการแก้ปัญหาข้างต้นในที่:

  • พวกเขาใช้ตัวอักษรโดยพลการอย่างชัดเจน (ทั่วไปมากขึ้นและเหมาะสมกับคำถามต้นฉบับที่ถามทั้งตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก)
  • สตริงที่มีความยาว N ทั้งหมดมีความน่าจะเป็นเท่ากับที่จะถูกส่งคืน (เช่นสตริงที่ไม่มีการซ้ำซ้อน)
  • พวกเขาจะขึ้นอยู่กับฟังก์ชั่นแผนที่มากกว่าเคล็ดลับ toString (36) ซึ่งทำให้พวกเขาตรงไปตรงมาและง่ายต่อการเข้าใจ

ดังนั้นพูดตัวอักษรที่คุณเลือกคือ

var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

จากนั้นทั้งสองนี้จะเทียบเท่ากันดังนั้นคุณสามารถเลือกได้ว่าคุณจะใช้วิธีใดให้ง่ายขึ้น:

Array(N).join().split(',').map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');

และ

Array.apply(null, Array(N)).map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');

แก้ไข:

ฉันดูเหมือนว่าqubyteและMartijn de Millianoมาพร้อมกับวิธีแก้ปัญหาที่คล้ายคลึงกับหลัง (รุ่งโรจน์!) ซึ่งฉันก็พลาดไป เนื่องจากพวกเขาไม่ได้มองสั้น ๆ ฉันจะทิ้งไว้ที่นี่ต่อไปในกรณีที่มีคนต้องการหนึ่งซับ :-)

นอกจากนี้แทนที่ 'new Array' ด้วย 'Array' ในโซลูชันทั้งหมดเพื่อกำจัดจำนวนไบต์ไม่กี่ไบต์


ทำไมไม่เพิ่มเพียง 1 (Math.random()+1).toString(36).substring(7);
emix

เนื่องจากการเพิ่ม 1 ไม่ได้แก้ปัญหาทั้งสองอย่างที่กล่าวถึงในที่นี้ ตัวอย่างเช่น (1) .toString (36) .substring (7) สร้างสตริงว่าง
amichair

การใช้Math.random().toString(36).substring(2,7)ให้ผลลัพธ์ที่คาดหวังซึ่งเป็นเหมือน.substring(2, n+2)
โจเซฟเร็กซ์

Array.apply(null, {length: 5}).map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('')
มูฮัมหมัดอูเมอร์

นี่เป็นสิ่งที่ดี แต่เมื่อดำเนินการใน Firefox ด้วย N = 16 ตัวเลขสุดท้าย ~ 6 หลักจะเป็นศูนย์ ... (แต่มันสนองความต้องการของ OP สำหรับการสุ่ม 5 ตัวอักษร)
Edward Newell

127

วิธีการแก้ปัญหาที่มีขนาดกะทัดรัดมากที่สุดเพราะจะสั้นกว่าslice substringการลบออกจากจุดสิ้นสุดของสตริงอนุญาตให้หลีกเลี่ยงสัญลักษณ์จุดลอยตัวที่สร้างโดยrandomฟังก์ชัน:

Math.random().toString(36).slice(-5);

หรือแม้กระทั่ง

(+new Date).toString(36).slice(-5);

อัปเดต:เพิ่มวิธีอีกหนึ่งวิธีโดยใช้btoaวิธี:

btoa(Math.random()).slice(0, 5);
btoa(+new Date).slice(-7, -2);
btoa(+new Date).substr(-7, 5);

// Using Math.random and Base 36:
console.log(Math.random().toString(36).slice(-5));

// Using new Date and Base 36:
console.log((+new Date).toString(36).slice(-5));

// Using Math.random and Base 64 (btoa):
console.log(btoa(Math.random()).slice(0, 5));

// Using new Date and Base 64 (btoa):
console.log(btoa(+new Date).slice(-7, -2));
console.log(btoa(+new Date).substr(-7, 5));


Math.random().toString(36).slice(-5);- ถ้าMath.random()ผลตอบแทน0.0?
x-ray

@ x-ray คุณจะได้รับ"0";)
Valentin Podkamennyi

2
เผง ;) และถ้าMath.random()ผลตอบแทนผลที่ได้คือ0.5 "0.i"ไม่แน่ใจว่ามีกรณีขอบอื่น ๆ หรือไม่ แค่ต้องการชี้ให้เห็นว่านี่ไม่ใช่คำตอบที่ถูกต้องสำหรับคำถาม (5 ตัวอักษรจาก [a-zA-Z0-9])
x-ray

2
@ x-ray ฉันจะไม่พูดว่านี่เป็นคำตอบที่ถูกต้องฉันแค่บอกว่านี่เป็นคำตอบ @doubletap เวอร์ชันกะทัดรัดข้างต้น ฉันเองใช้(+new Date + Math.random())เพื่อป้องกันกรณีนี้ อย่างไรก็ตามขอขอบคุณสำหรับการบันทึก
Valentin Podkamennyi

1
นี้. ฉันไม่รู้ว่าทำไมคำตอบอื่น ๆ จึงต้องใช้รหัสมาก
john ktejik

100

สิ่งนี้จะทำงานได้ดี

function randomString(len, charSet) {
    charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    var randomString = '';
    for (var i = 0; i < len; i++) {
        var randomPoz = Math.floor(Math.random() * charSet.length);
        randomString += charSet.substring(randomPoz,randomPoz+1);
    }
    return randomString;
}

โทรด้วยชุดอักขระเริ่มต้น [a-zA-Z0-9] หรือส่งด้วยตนเอง:

var randomValue = randomString(5);

var randomValue = randomString(5, 'PICKCHARSFROMTHISSET');

ตัวอย่างที่นี่มีให้เลือกหลากหลาย: mediacollege.com/internet/javascript/number/random.html
David

1
อาจมีเพียงพร่องlenโดยตรงในwhileวง
drzaus

ขอบคุณฉันเพิ่งโพสต์รูปแบบกาแฟที่ด้านล่างของตัวอย่างนี้: stackoverflow.com/a/26682781/262379
Dinis Cruz

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

ไม่ยอมใครง่ายๆสวยทำงานให้ฉันขอบคุณ!
Zaki Mohammed

73

รุ่นที่ใหม่กว่าพร้อมตัวดำเนินการes6 :

[...Array(30)].map(() => Math.random().toString(36)[2]).join('')

  • 30เป็นจำนวนพลคุณสามารถเลือกระยะเวลาในโทเค็นที่คุณต้องการ
  • นี่36คือหมายเลข Radix สูงสุดที่คุณสามารถส่งไปยังnumeric.toString ()ซึ่งหมายถึงตัวเลขทั้งหมดและตัวอักษรตัวพิมพ์เล็ก az
  • 2จะใช้ในการรับดัชนีที่ 3 จากสตริงแบบสุ่มซึ่งมีลักษณะเช่นนี้"0.mfbiohx64i"เราอาจจะใช้ดัชนีใด ๆ หลังจากที่0.

คุณอธิบายได้ไหม โดยเฉพาะอย่างยิ่งทำไมคุณผ่าน 36 ถึง toString () และทำไมคุณถึงเลือกองค์ประกอบที่ 3
vuza

5
นี่เป็นทางออกที่ดีที่สุด
เอาชนะ

ดี แต่โซลูชันนี้ไม่รวมอักขระ [AZ] ตามคำถามที่ร้องขอเพียง [a-z0-9]
Nahuel Greco

71

function randomstring(L) {
  var s = '';
  var randomchar = function() {
    var n = Math.floor(Math.random() * 62);
    if (n < 10) return n; //1-10
    if (n < 36) return String.fromCharCode(n + 55); //A-Z
    return String.fromCharCode(n + 61); //a-z
  }
  while (s.length < L) s += randomchar();
  return s;
}
console.log(randomstring(5));


ฉันชอบสิ่งนี้ที่สุด คุณสามารถแก้ไขได้อย่างง่ายดายเพื่อยอมรับพารามิเตอร์เพิ่มเติมและส่งคืนเฉพาะจำนวนที่ต่ำกว่าหรือตัวพิมพ์ใหญ่ ฉันไม่คิดว่ารูปแบบการบีบอัดแบบพิเศษเป็นสิ่งจำเป็นwhile(s.length< L) s+= randomchar();
mastaBlasta

3
นอกจากนี้ยังwhile(L--)จะทำ
vSync

1
ดีกว่าที่จะใช้ที่แข็งแกร่งมากขึ้น'A'.charCodeAt(0)มากกว่าจำนวนเวทย์มนตร์55(และเช่นเดียวกันสำหรับ61) 65โดยเฉพาะอย่างยิ่งตั้งแต่บนแพลตฟอร์มอยู่ดีของฉันจำนวนมายากลที่เป็นผลตอบแทน รหัสนั้นจะดีกว่าเอกสารด้วยตนเองเช่นกัน
Grumdrig

ฉันสร้างการปรับขนาด minification ที่เหมาะสมที่สุด (เล็กกว่า 46 ไบต์) ที่นี่: stackoverflow.com/a/52412162
Waruyama

ขอให้โชคดีที่แก้จุดบกพร่องที่ @Waruyama นั่นคือ webpack สำหรับ!
Dylan Watson

61

เครื่องกำเนิดสตริงแบบสุ่ม (อัลฟ่า - ตัวเลข | อัลฟา | ตัวเลข)

/**
 * Pseudo-random string generator
 * http://stackoverflow.com/a/27872144/383904
 * Default: return a random alpha-numeric string
 * 
 * @param {Integer} len Desired length
 * @param {String} an Optional (alphanumeric), "a" (alpha), "n" (numeric)
 * @return {String}
 */
function randomString(len, an) {
  an = an && an.toLowerCase();
  var str = "",
    i = 0,
    min = an == "a" ? 10 : 0,
    max = an == "n" ? 10 : 62;
  for (; i++ < len;) {
    var r = Math.random() * (max - min) + min << 0;
    str += String.fromCharCode(r += r > 9 ? r < 36 ? 55 : 61 : 48);
  }
  return str;
}

console.log(randomString(10));      // i.e: "4Z8iNQag9v"
console.log(randomString(10, "a")); // i.e: "aUkZuHNcWw"
console.log(randomString(10, "n")); // i.e: "9055739230"


ในขณะที่ข้างต้นใช้การตรวจสอบเพิ่มเติมสำหรับเอาท์พุทA / N, A, N ที่ต้องการลองแบ่งมันออกเป็นส่วนที่จำเป็น (เฉพาะตัวเลขอัลฟ่าเท่านั้น) เพื่อความเข้าใจที่ดีขึ้น:

  • สร้างฟังก์ชั่นที่ยอมรับการโต้แย้ง (ความยาวที่ต้องการของผลลัพธ์สตริงแบบสุ่ม)
  • สร้างสตริงว่างที่ต้องการvar str = "";เชื่อมโยงอักขระสุ่ม
  • ภายในลูปสร้างrandหมายเลขดัชนีจาก0 ถึง 61 (0..9 + A..Z + a..z = 62)
  • สร้างตรรกะตามเงื่อนไขเพื่อปรับ / แก้ไขrand (เนื่องจากเป็น 0..61) การเพิ่มขึ้นด้วยตัวเลขบางตัว (ดูตัวอย่างด้านล่าง) เพื่อรับกลับCharCodeหมายเลขที่ถูกต้องและตัวละครที่เกี่ยวข้อง
  • ภายในวงเชื่อมต่อกับstraString.fromCharCode( incremented rand )

มาดูช่วงของตารางอักขระ ASCII :

_____0....9______A..........Z______a..........z___________  Character
     | 10 |      |    26    |      |    26    |             Tot = 62 characters
    48....57    65..........90    97..........122           CharCode ranges

Math.floor( Math.random * 62 )ให้ช่วงจาก0..61(สิ่งที่เราต้องการ)
ลองแก้ไขการสุ่มเพื่อให้ได้ช่วง charCode ที่ถูกต้อง:

      |   rand   | charCode |  (0..61)rand += fix            = charCode ranges |
------+----------+----------+--------------------------------+-----------------+
0..9  |   0..9   |  48..57  |  rand += 48                    =     48..57      |
A..Z  |  10..35  |  65..90  |  rand += 55 /*  90-35 = 55 */  =     65..90      |
a..z  |  36..61  |  97..122 |  rand += 61 /* 122-61 = 61 */  =     97..122     |

การดำเนินการตามเงื่อนไขตรรกะจากตารางข้างต้น

   rand += rand>9 ? ( rand<36 ? 55 : 61 ) : 48 ;
// rand +=  true  ? (  true   ? 55 else 61 ) else 48 ;

จากคำอธิบายด้านบนนี่คือตัวอย่างข้อมูลที่เป็นตัวอักษรและตัวเลข :

function randomString(len) {
  var str = "";                                // String result
  for (var i = 0; i < len; i++) {              // Loop `len` times
    var rand = Math.floor(Math.random() * 62); // random: 0..61
    var charCode = rand += rand > 9 ? (rand < 36 ? 55 : 61) : 48; // Get correct charCode
    str += String.fromCharCode(charCode);      // add Character to str
  }
  return str; // After all loops are done, return the concatenated string
}

console.log(randomString(10)); // i.e: "7GL9F0ne6t"

หรือถ้าคุณจะ:

const randomString = (n, r='') => {
  while (n--) r += String.fromCharCode((r=Math.random()*62|0, r+=r>9?(r<36?55:61):48));
  return r;
};

console.log(randomString(10))


33

วิธีที่ง่ายที่สุดคือ:

(new Date%9e6).toString(36)

สิ่งนี้จะสร้างสตริงสุ่ม 5 ตัวอักษรตามเวลาปัจจุบัน ตัวอย่างการแสดงผลเป็น4mtxjหรือ4mv90หรือ4mwp1

ปัญหานี้คือถ้าคุณเรียกมันสองครั้งในวินาทีเดียวกันมันจะสร้างสตริงเดียวกัน

วิธีที่ปลอดภัยกว่าคือ:

(0|Math.random()*9e6).toString(36)

สิ่งนี้จะสร้างสตริงแบบสุ่มที่มีอักขระ 4 หรือ 5 ตัวแตกต่างกันเสมอ ตัวอย่างการแสดงผลเป็นเหมือน30jzmหรือ1r591หรือ4su1a

ในทั้งสองวิธีส่วนแรกสร้างตัวเลขสุ่ม .toString(36)ส่วนหนึ่งโยนตัวเลขเพื่อเป็นตัวแทน base36 (alphadecimal) ของมัน


ฉันไม่แน่ใจว่าวิธีนี้ตอบคำถาม; นี่เป็นคำถามอายุ 7 ปีที่มีคำตอบที่ถูกต้องอยู่แล้ว หากคุณเลือกที่จะให้คำตอบใหม่คุณควรระมัดระวังเป็นพิเศษเพื่อให้แน่ใจว่าคำตอบของคุณได้รับการอธิบายและจัดทำเป็นเอกสารไว้อย่างดี
Claies

1
ถ้าคุณใช้ Date ทำไมคุณไม่ใช้มันเหมือน:(+new Date).toString(36)
Seniorpreacher

ฉันชอบโซลูชันตัวเลขสุ่มของคุณ แต่ 9e6 ให้ความเป็นไปได้เพียง 9 ล้านตัวจาก 60.4 ล้านตัวสำหรับ 5 หลัก (36 ^ 5) ดังนั้นคุณสามารถแทนที่มันด้วย(0|Math.random()*6.04e7).toString(36)เพื่อให้ครอบคลุมได้
เลอ Droid

1
ฉันต้องการสตริงสุ่มแบบยาวที่มีรูทีนสั้นที่สุดเท่าที่จะเป็นไปได้ (สำหรับการสาธิตโค้ด) ที่ไม่จำเป็นต้องมีการเข้ารหัสที่น่าอัศจรรย์ ฉันชอบคำตอบนี้ดีที่สุด (อันที่สองของคุณ) ดังนั้นขอบคุณ สองเซ็นต์ของฉัน: ฉันสามารถเอาชนะมันถี่กับหนึ่งในการกดแป้นพิมพ์น้อยลงและโดยปกติจะผลิต 13 ตัวอักษรแบบสุ่ม (Math.random()*1e20).toString(36)(ไม่รวมระยะเวลา):
Andrew Willems

หนึ่ง qualm ที่ฉันมีกับคำตอบนี้คือจะไม่ใช้ [AZ] ซึ่งเกิดขึ้นกับคำถามดั้งเดิม
มิตร

22

นี่คือ liners หนึ่งง่าย ๆ เปลี่ยนnew Array(5)เพื่อตั้งความยาว

รวมไปถึง 0-9a-z

new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36);})

รวมไปถึง 0-9a-zA-Z

new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36)[Math.random()<.5?"toString":"toUpperCase"]();});

20

ฉันรู้ว่าทุกคนเข้าใจถูกต้องแล้ว แต่ฉันรู้สึกอยากไปที่นี่ด้วยวิธีที่เบาที่สุดเท่าที่จะเป็นไปได้ (เขียนรหัสไม่ใช่ซีพียู):

function rand(length, current) {
  current = current ? current : '';
  return length ? rand(--length, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz".charAt(Math.floor(Math.random() * 60)) + current) : current;
}

console.log(rand(5));

ต้องใช้เวลาสักครู่เพื่อตัดหัวของคุณ แต่ฉันคิดว่ามันแสดงให้เห็นว่าไวยากรณ์ของจาวาสคริปต์นั้นยอดเยี่ยมแค่ไหน


20
หากคุณกำลังพยายามที่จะทำให้รหัสสั้นทำไมเขียนcurrent = current ? current : '';เมื่อคุณสามารถเขียนcurrent = current || '';
CaffGeek

9
ตั้งแต่ที่เรากำลังพูดถึงการเพิ่มประสิทธิภาพของไมโครที่นี่ที่จริงผมจะแนะนำให้ข้ามการกำหนดตัวแปรทั้งหมดถ้าไม่จำเป็น:current || (current = '');
โทมัส Heymann

ความพยายามในการเพิ่มประสิทธิภาพขนาดเล็กในขณะที่ใช้ "ดี" แต่อัลกอริธึมการทำซ้ำที่สิ้นเปลืองทรัพยากรไม่มีเหตุผล :-) A สำหรับลูปยังคงดีที่สุดใน Javascript และการเรียกซ้ำครั้งใหญ่จนกว่าจะมีความก้าวหน้าครั้งใหญ่
Mörre

17

หากคุณใช้LodashหรือUnderscore แสดงว่าง่ายมาก:

var randomVal = _.sample('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 5).join('');

6
Lodash ใช้งาน_.sampleSize('asdfgh',5).join('')
marlo

2
นี่ไม่ใช่ทางออกที่ดีเพราะเอกสารแต่ละตัวนั้นมาจากดัชนีที่ไม่ซ้ำกัน นั่นหมายความว่ามันไม่ได้สุ่มอย่างแท้จริงเนื่องจากไม่มีตัวละครที่สามารถ / จะทำซ้ำได้
random_user_name

16

เพื่อตอบสนองความต้องการ [a-zA-Z0-9] และ length = 5 ใช้

btoa(Math.random()).substr(5, 5);

ตัวพิมพ์เล็กตัวอักษรตัวพิมพ์ใหญ่และตัวเลขจะเกิดขึ้น


1
ฉันเดา Math.random () อาจนำไปสู่ ​​base64-string ที่มีอักขระน้อยเกินไป
Leif

14

ในกรณีที่ทุกคนสนใจซับใน (แม้ว่าจะไม่ได้ฟอร์แมตเช่นนี้เพื่อความสะดวกของคุณ) ที่จัดสรรหน่วยความจำทันที (แต่โปรดสังเกตว่าสำหรับสตริงเล็ก ๆ มันไม่สำคัญ) นี่คือวิธีทำ

Array.apply(0, Array(5)).map(function() {
    return (function(charset){
        return charset.charAt(Math.floor(Math.random() * charset.length))
    }('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'));
}).join('')

คุณสามารถแทนที่5ด้วยความยาวของสตริงที่คุณต้องการ ขอขอบคุณที่ @AriyaHidayat ในโพสต์นี้สำหรับการแก้ปัญหาให้กับฟังก์ชั่นไม่ได้ทำงานกับอาร์เรย์เบาบางสร้างขึ้นโดยmapArray(5)


13
ทุกโปรแกรมจาวาสคริปต์คือ 'หนึ่งซับ' ถ้าคุณจัดรูปแบบดังกล่าว
hacklikecrack

13

นี่คือวิธีที่ฉันสร้าง
มันจะสร้างสตริงที่มีทั้งตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก
นอกจากนี้ฉันได้รวมฟังก์ชั่นที่จะสร้างสตริงตัวอักษรและตัวเลขด้วย

ตัวอย่างการทำงาน:
http://jsfiddle.net/greatbigmassive/vhsxs/ (อัลฟาเท่านั้น)
http://jsfiddle.net/greatbigmassive/PJwg8/ (ตัวอักษรและตัวเลข)

function randString(x){
    var s = "";
    while(s.length<x&&x>0){
        var r = Math.random();
        s+= String.fromCharCode(Math.floor(r*26) + (r>0.5?97:65));
    }
    return s;
}

อัปเกรดกรกฎาคม 2558
สิ่งนี้ทำในสิ่งเดียวกัน แต่มีเหตุผลมากกว่าและรวมถึงตัวอักษรทั้งหมด

var s = "";
while(s.length<x&&x>0){
    v = Math.random()<0.5?32:0;
    s += String.fromCharCode(Math.round(Math.random()*((122-v)-(97-v))+(97-v)));
}

ด้วยฟังก์ชั่นนี้คุณจะไม่สามารถรับตัวอักษรตัวพิมพ์ใหญ่ได้มากกว่า 'M' หรืออักษรตัวพิมพ์เล็กที่น้อยกว่า 'n'
erkanyildiz

จริงๆ? โอ! อาจจะทดสอบมากกว่านี้ อย่างไรก็ตามอืมเนื่องจากมันเป็นสตริงสุ่มและเราไม่สนใจว่าตัวอักษรอยู่ในนั้น (ตราบเท่าที่พวกมันสุ่ม) แล้วมันก็ยังทำในสิ่งที่เราต้องการให้ทำซึ่งเป็นเรื่องที่สำคัญ แต่ใช่จะให้ อัพเกรดขอบคุณ
อดัม

12

สมมติว่าคุณใช้เครื่องหมายขีดล่างเป็นไปได้ที่จะสร้างสตริงแบบสุ่มอย่างหรูหราในสองบรรทัด:

var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var random = _.sample(possible, 5).join('');

6
สิ่งนี้จะทำให้ค่าที่ส่งคืนมีตัวอักษรที่ไม่ซ้ำกันทั้งหมด นอกจากนี้ความยาวของสตริงจะถูก จำกัด จนถึงความยาวของ var ที่เป็นไปได้
Yefu

10
const c = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
const s = [...Array(5)].map(_ => c[~~(Math.random()*c.length)]).join('')

วิธีแก้ปัญหาที่ง่ายและสะอาด
Mark Swardstrom

สิ่งนี้สมควรได้รับ +1 ที่ใหญ่กว่า
Walid Ammar

10

อัลกอริทึมที่รวดเร็วและปรับปรุง ไม่รับประกันเครื่องแบบ (ดูความคิดเห็น)

function getRandomId(length) {
    if (!length) {
        return '';
    }

    const possible =
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let array;

    if ('Uint8Array' in self && 'crypto' in self && length <= 65536) {
        array = new Uint8Array(length);
        self.crypto.getRandomValues(array);
    } else {
        array = new Array(length);

        for (let i = 0; i < length; i++) {
            array[i] = Math.floor(Math.random() * 62);
        }
    }

    let result = '';

    for (let i = 0; i < length; i++) {
        result += possible.charAt(array[i] % 62);
    }

    return result;
}

2
คำตอบที่ยอดเยี่ยม แต่ความน่าจะเป็นนั้นไม่เหมือนกัน มีอักขระ 62 ตัวที่เป็นไปได้และcrypto.getRandomValuesส่งคืนค่าหนึ่งใน 256 ค่าที่ไม่ซ้ำกัน เนื่องจาก 256 ไม่หารด้วย 62 คุณจึงมีโอกาสสูงที่จะได้รับตัวอักษร AH เล็กน้อย ฉันคิดว่าทางออกที่ดีที่สุดคือทำในสิ่งที่ YouTube ทำและเพียงเพิ่มตัวละครเพิ่มเติมอีก 2 ตัว (อาจ-และ_) ลงในชุดอักขระ อย่างไรก็ตามการทำงานที่ดี - คำตอบนี้ต้องการความรักมากขึ้น :)
TeWu

การเพิ่ม - และ _ เป็นความคิดที่ดีเพราะมันจะทำให้คุณได้รับชุด url-safe ที่สมบูรณ์แบบ
64

8

ปัญหาเกี่ยวกับการตอบสนองต่อ"ผมต้องสตริงสุ่ม"คำถาม (ในภาษาใด) เป็นวิธีการแก้ปัญหาในทางปฏิบัติทุกใช้สเปคหลักข้อบกพร่องของความยาวสาย คำถามตัวเองไม่ค่อยเปิดเผยว่าทำไมต้องมีสตริงสุ่ม แต่ฉันขอท้าให้คุณไม่ค่อยต้องการสตริงที่มีความยาวสุ่มบอกว่า 8 สิ่งที่คุณต้องการเสมอคือสตริงพิเศษจำนวนหนึ่งตัวอย่างเช่นใช้เป็นตัวระบุสำหรับวัตถุประสงค์บางอย่าง

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

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

และนี่คือที่ห้องสมุดเช่นEntropyStringสามารถช่วยได้ ในการสร้างรหัสสุ่มที่มีน้อยกว่า 1 ในโอกาสล้านล้านที่จะทำซ้ำใน 5 ล้านสตริงโดยใช้entropy-string:

import {Random, Entropy} from 'entropy-string'

const random = new Random()
const bits = Entropy.bits(5e6, 1e12)

const string = random.string(bits)

"44hTNghjNHGGRHqH9"

entropy-stringใช้ชุดอักขระที่มี 32 อักขระโดยค่าเริ่มต้น มีชุดอักขระที่กำหนดไว้ล่วงหน้าอื่น ๆ และคุณสามารถระบุอักขระของคุณเองได้เช่นกัน ตัวอย่างเช่นการสร้าง ID ด้วยเอนโทรปีเดียวกันกับด้านบน แต่ใช้อักขระฐานสิบหก:

import {Random, Entropy, charSet16} from './entropy-string'

const random = new Random(charSet16)
const bits = Entropy.bits(5e6, 1e12)

const string = random.string(bits)

"27b33372ade513715481f"

บันทึกความแตกต่างของความยาวสตริงเนื่องจากความแตกต่างของจำนวนอักขระทั้งหมดในชุดอักขระที่ใช้ ความเสี่ยงในการทำซ้ำตามจำนวนสายอักขระที่ระบุอาจเหมือนกัน ความยาวสตริงไม่ใช่ และที่สำคัญที่สุดคือความเสี่ยงในการทำซ้ำและจำนวนสายอักขระที่ชัดเจน ไม่ต้องเดาอีกต่อไปกับความยาวสตริง


7
function randomString (strLength, charSet) {
    var result = [];

    strLength = strLength || 5;
    charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    while (--strLength) {
        result.push(charSet.charAt(Math.floor(Math.random() * charSet.length)));
    }

    return result.join('');
}

นี่สะอาดเท่าที่จะได้รับ มันรวดเร็วเกินไปhttp://jsperf.com/ay-random-string


สำหรับฉันนี้มักจะสร้างสตริงแบบสุ่มด้วยstrLength - 1: - /
xanderiel

3
เปลี่ยนจาก--strLengthเป็นstrLength--แก้ไขให้ฉัน
xanderiel

7

คุณสามารถวนซ้ำอาร์เรย์ของรายการและเพิ่มไปยังตัวแปรสตริงซ้ำตัวอย่างเช่นหากคุณต้องการลำดับดีเอ็นเอแบบสุ่ม:

function randomDNA(len) {
  len = len || 100
  var nuc = new Array("A", "T", "C", "G")
  var i = 0
  var n = 0
  s = ''
  while (i <= len - 1) {
    n = Math.floor(Math.random() * 4)
    s += nuc[n]
    i++
  }
  return s
}

console.log(randomDNA(5));


6

ฉันไม่พบโซลูชันที่สะอาดสำหรับการสนับสนุนทั้งตัวพิมพ์เล็กและตัวพิมพ์ใหญ่

รองรับตัวพิมพ์เล็กเท่านั้น:

Math.random().toString(36).substr(2, 5)

การสร้างโซลูชันนั้นเพื่อรองรับตัวพิมพ์เล็กและตัวพิมพ์ใหญ่:

Math.random().toString(36).substr(2, 5).split('').map(c => Math.random() < 0.5 ? c.toUpperCase() : c).join('');

เปลี่ยน5ในsubstr(2, 5)การปรับความยาวได้ตามที่คุณต้องการ


6

หนึ่งในสายการบิน:

Array(15).fill(null).map(() => Math.random().toString(36).substr(2)).join('')
// Outputs: 0h61cbpw96y83qtnunwme5lxk1i70a6o5r5lckfcyh1dl9fffydcfxddd69ada9tu9jvqdx864xj1ul3wtfztmh2oz2vs3mv6ej0fe58ho1cftkjcuyl2lfkmxlwua83ibotxqc4guyuvrvtf60naob26t6swzpil

เพื่อให้อาร์กิวเมนต์การเปลี่ยนแปลงสั้นลงในArray(15)ค่าที่น้อยลง Array(4)เช่น:
แอนดรู

ฉันรักโซลูชันนี้เรียบง่ายและชัดเจน มันกำลังสร้างตัวเลขสุ่ม 15 หมายเลขระหว่าง 0 ถึง 1 สร้างเลขฐานสิบหกจากนั้นนำสองตัวอักษรแรกออก ในที่สุดมันก็รวมกันทั้งหมดเข้าด้วยกัน
Siscia

5

ใช้งานได้อย่างแน่นอน

<script language="javascript" type="text/javascript">
function randomString() {
 var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
 var string_length = 8;
 var randomstring = '';
 for (var i=0; i<string_length; i++) {
  var rnum = Math.floor(Math.random() * chars.length);
  randomstring += chars.substring(rnum,rnum+1);
 }
 document.randform.randomfield.value = randomstring;
}
</script>

5

สิ่งที่เกี่ยวกับเรื่องนี้: Date.now().toString(36) ไม่สุ่มมาก แต่สั้นและไม่เหมือนใครทุกครั้งที่คุณเรียกมัน


1
น่าเสียดายที่นี่จะไม่ซ้ำกันเนื่องจากDate.now()มีความละเอียดเป็นมิลลิวินาทีเท่านั้น ยกตัวอย่างเช่นเมื่อทำงานในลูปธรรมดาคุณจะได้รับข้อมูลซ้ำซ้อนมากมาย for (let i = 0; i < 10; ++i) { console.log(Date.now().toString(36)); }.
เนท

5

ตัวอักษรและตัวเลขแบบตัวเล็ก

function randStr(len) {
  let s = '';
  while (s.length < len) s += Math.random().toString(36).substr(2, len - s.length);
  return s;
}

// usage
console.log(randStr(50));

ประโยชน์ของฟังก์ชั่นนี้คือคุณจะได้รับความยาวสตริงที่แตกต่างกันและมันช่วยให้มั่นใจความยาวของสตริง

ตัวพิมพ์เล็กทั้งหมดตัวพิมพ์เล็ก:

function randStr(len) {
  let s = '';
  while (len--) s += String.fromCodePoint(Math.floor(Math.random() * (126 - 33) + 33));
  return s;
}

// usage
console.log(randStr(50));

Custom Chars

function randStr(len, chars='abc123') {
  let s = '';
  while (len--) s += chars[Math.floor(Math.random() * chars.length)];
  return s;
}

// usage
console.log(randStr(50));
console.log(randStr(50, 'abc'));
console.log(randStr(50, 'aab')); // more a than b


คำตอบนี้มีมากขึ้นสำหรับกรณีการใช้งานของฉัน มันจะเจ๋งถ้าคุณสามารถเพิ่มสิ่งที่var possibleชอบในคำตอบที่ยอมรับได้ดังนั้นผลลัพธ์ของฟังก์ชันนั้นสามารถกำหนดค่าได้มากกว่า
Denis.Sabolotni

4

สร้างสตริงที่มีความยาว 10 ตัวอักษร ความยาวถูกกำหนดโดยพารามิเตอร์ (ค่าเริ่มต้น 10)

function random_string_generator(len) {
var len = len || 10;
var str = '';
var i = 0;

for(i=0; i<len; i++) {
    switch(Math.floor(Math.random()*3+1)) {
        case 1: // digit
            str += (Math.floor(Math.random()*9)).toString();
        break;

        case 2: // small letter
            str += String.fromCharCode(Math.floor(Math.random()*26) + 97); //'a'.charCodeAt(0));
        break;

        case 3: // big letter
            str += String.fromCharCode(Math.floor(Math.random()*26) + 65); //'A'.charCodeAt(0));
        break;

        default:
        break;
    }
}
return str;
}

4

คุณสามารถใช้coderain มันเป็นห้องสมุดในการสร้างรหัสสุ่มตามรูปแบบที่กำหนด ใช้#เป็นตัวยึดตำแหน่งสำหรับอักขระส่วนบนและตัวพิมพ์เล็กรวมถึงตัวเลข:

var cr = new CodeRain("#####");
console.log(cr.next());

มีตัวยึดอื่น ๆ เช่นAตัวอักษรตัวพิมพ์ใหญ่หรือ9ตัวเลข

สิ่งที่อาจมีประโยชน์คือการโทร.next()จะให้ผลลัพธ์ที่เป็นเอกลักษณ์เสมอดังนั้นคุณไม่ต้องกังวลกับการซ้ำซ้อน

นี่คือโปรแกรมการสาธิตที่สร้างรายการของรหัสสุ่มที่ไม่ซ้ำกัน

การเปิดเผยแบบเต็ม: ฉันเป็นผู้เขียนโคเด็นain


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