สร้างสตริงรหัสผ่านแบบสุ่มพร้อมข้อกำหนดในจาวาสคริปต์


96

ฉันต้องการสร้างสตริงสุ่มที่ต้องมี 5 ตัวอักษรจาก az และ 3 ตัวเลข

ฉันจะทำสิ่งนี้ด้วย JavaScript ได้อย่างไร?

ฉันมีสคริปต์ต่อไปนี้ แต่ไม่ตรงตามข้อกำหนดของฉัน

        var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        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);
        }

6
ถ้าตรงตามความต้องการของคุณคำถามคืออะไร? นอกจากนี้ข้อกำหนดรหัสผ่านที่บังคับของคุณเป็นความคิดที่ไม่ดี
Rob W


3
new Array(12).fill().map(() => String.fromCharCode(Math.random()*86+40)).join("") Nifty one ซับในการสร้างรหัสผ่าน 12 ตัวอักษรพร้อมตัวอักษรพิเศษบนตัวเลขล่างในวิธีการที่เบามาก
Tofandel

คำตอบ:


318

การบังคับให้อักขระจำนวนคงที่เป็นความคิดที่ไม่ดี ไม่ได้ปรับปรุงคุณภาพของรหัสผ่าน ที่แย่กว่านั้นคือลดจำนวนรหัสผ่านที่เป็นไปได้เพื่อให้การแฮ็กโดย bruteforcing ทำได้ง่ายขึ้น

ในการสร้างคำสุ่มที่ประกอบด้วยอักขระที่เป็นตัวอักษรและตัวเลขให้ใช้:

var randomstring = Math.random().toString(36).slice(-8);

มันทำงานอย่างไร?

Math.random()                        // Generate random number, eg: 0.123456
             .toString(36)           // Convert  to base-36 : "0.4fzyo82mvyr"
                          .slice(-8);// Cut off last 8 characters : "yo82mvyr"

เอกสารสำหรับNumber.prototype.toStringและstring.prototype.sliceวิธีการ


6
ฉันเห็นด้วย แต่บางครั้งคุณก็ไม่
กล้า

40
อย่าใช้สิ่งนี้: เนื่องจากตัวเลขถูกแปลงจากไบนารีเป็นฐานสิบและมีบิตไม่เพียงพอที่จะ "เติมเต็ม" ในช่องว่างทศนิยมเต็มจำนวนหลักสุดท้ายจะถูกเลือกจากชุดค่าบางค่าเท่านั้น ตัวอย่างเช่นในคอมพิวเตอร์ของฉันตัวเลขสุดท้ายจะเป็น "i", "r" และ "9" เท่านั้น ใช้สิ่งนี้แทน:Math.random().toString(36).substr(2, 8)
Joel

1
เพื่ออธิบายสิ่งที่ 36 ทำ: จากmozilla วิธี toString () จะแยกวิเคราะห์อาร์กิวเมนต์แรกและพยายามส่งคืนการแสดงสตริงในรัศมี (ฐาน) ที่ระบุ สำหรับรัศมีที่สูงกว่า 10 ตัวอักษรของตัวอักษรจะแสดงตัวเลขที่มากกว่า 9 ตัวอย่างเช่นสำหรับเลขฐานสิบหก (ฐาน 16) จะใช้ a ถึง f ตามนี้โดยใช้ radix 36 เราจะได้ az หลัง 0-9
Shishir Gupta

2
@ShishirGupta .toStringยอมรับเฉพาะฐานถึง 36 เท่านั้นคำตอบนี้หมายถึงซับเดียวสำหรับสตริงสุ่มที่ไม่ใช่การเข้ารหัส หากคุณต้องการมีตัวพิมพ์ใหญ่ให้ใช้Math.random(หรือcrypto.getRandomValuesถ้ามี) และแมปผลลัพธ์เป็น az, AZ, 0-9 ตัวอย่างเช่นการใช้คำตอบของ saaj ด้านล่าง
Rob W

1
ไม่เห็นว่าสิ่งนี้ตอบสนองความต้องการของ OP "5 ตัวอักษรจาก az และ 3 ตัวเลข"ได้อย่างไร ฉันเข้าใจแล้วผู้เขียนคิดว่านั่นเป็นความคิดที่ไม่ดี ... แต่มันก็เป็นข้อกำหนด
mwag

39

แนวทางที่ดูแลรักษาได้และปลอดภัยกว่าเล็กน้อย

การอัปเดตเพื่อขยายความหมายและวิธีการทำงาน

  1. การรักษาความปลอดภัย MDN ค่อนข้างชัดเจนเกี่ยวกับการใช้งานMath.random เพื่อความปลอดภัย :

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

    เมื่อดูที่can-i-usegetRandomValuesในปี 2020 คุณอาจไม่จำเป็นต้องใช้msCryptoและทางMath.randomเลือกอื่นอีกต่อไปเว้นแต่คุณจะสนใจเบราว์เซอร์โบราณ

  2. การบำรุงรักษาส่วนใหญ่เกี่ยวกับRegExp _patternวิธีง่ายๆในการกำหนดคลาสอักขระที่คุณอนุญาตในรหัสผ่าน แต่ยังเกี่ยวกับ 3 สิ่งที่แต่ละอย่างทำงาน: กำหนดรูปแบบรับไบต์แบบสุ่มอย่างปลอดภัยที่สุดให้ API สาธารณะเพื่อรวมทั้งสองอย่างเข้าด้วยกัน

var Password = {
 
  _pattern : /[a-zA-Z0-9_\-\+\.]/,
  
  
  _getRandomByte : function()
  {
    // http://caniuse.com/#feat=getrandomvalues
    if(window.crypto && window.crypto.getRandomValues) 
    {
      var result = new Uint8Array(1);
      window.crypto.getRandomValues(result);
      return result[0];
    }
    else if(window.msCrypto && window.msCrypto.getRandomValues) 
    {
      var result = new Uint8Array(1);
      window.msCrypto.getRandomValues(result);
      return result[0];
    }
    else
    {
      return Math.floor(Math.random() * 256);
    }
  },
  
  generate : function(length)
  {
    return Array.apply(null, {'length': length})
      .map(function()
      {
        var result;
        while(true) 
        {
          result = String.fromCharCode(this._getRandomByte());
          if(this._pattern.test(result))
          {
            return result;
          }
        }        
      }, this)
      .join('');  
  }    
    
};
<input type='text' id='p'/><br/>
<input type='button' value ='generate' onclick='document.getElementById("p").value = Password.generate(16)'>


นอกจากนี้สิ่งนี้ไม่ได้เพิ่มตัวเลขลงในโค้ดที่สร้างขึ้นเสมอไปและ OP ต้องการขั้นต่ำ 3
qwertzman

พบไลบรารีที่รองรับ window.crypto.getRandomValues ​​และทำงานใน node.js เช่นกันgithub.com/bermi/password-generator
Eugene

แค่อยากจะบอกว่าฉันต้องการบางอย่างเพื่อสร้างรหัสผ่านในเวลาอันรวดเร็วและนี่ก็สมบูรณ์แบบ ขอบคุณ!
Kyle K

30

คำตอบจำนวนมาก (รวมทั้งต้นฉบับของคำตอบนี้) ไม่ได้ระบุข้อกำหนดเกี่ยวกับตัวอักษรและจำนวนนับของ OP ด้านล่างนี้เป็นวิธีแก้ปัญหาสองวิธี: ทั่วไป (ไม่มีตัวอักษร / ตัวเลขขั้นต่ำ) และด้วยกฎ

ทั่วไป:

ฉันเชื่อว่านี่เป็นวิธีแก้ปัญหาทั่วไปที่ดีกว่าข้างต้นเนื่องจาก:

  • มีความปลอดภัยมากกว่าคำตอบที่ได้รับการยอมรับ / ได้รับการโหวตสูงสุดและยังมีความหลากหลายมากกว่าเนื่องจากรองรับชุดถ่านในลักษณะที่คำนึงถึงตัวพิมพ์เล็กและใหญ่
  • มันกระชับกว่าคำตอบอื่น ๆ (สำหรับวิธีแก้ปัญหาทั่วไปสูงสุด 3 บรรทัดสามารถเป็นซับเดียวได้)
  • ใช้เฉพาะ Javascript ดั้งเดิม - ไม่จำเป็นต้องติดตั้งหรือ libs อื่น ๆ

โปรดทราบว่า

  • เพื่อให้ใช้งานได้กับ IE ต้นแบบ Array.fill () ต้องเป็นpolyfilled
  • ถ้ามีควรใช้ window.crypto.getRandomValues ​​() แทน Math.random () (ขอบคุณ @BenjaminH ที่ชี้ให้เห็น)

สามซับ:

var pwdChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var pwdLen = 10;
var randPassword = Array(pwdLen).fill(pwdChars).map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('');

หรือเป็นซับเดียว:

var randPassword = Array(10).fill("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz").map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('');

ด้วยกฎตัวอักษร / ตัวเลข

ตอนนี้รูปแบบด้านบน สิ่งนี้จะสร้างสตริงแบบสุ่มสามสตริงจากชุดอักขระที่กำหนด (ตัวอักษรตัวเลขอย่างใดอย่างหนึ่ง) จากนั้นจึงแย่งผลลัพธ์

โปรดทราบว่าด้านล่างนี้ใช้ sort () เพื่อเป็นภาพประกอบเท่านั้น สำหรับการใช้งานในการผลิตแทนด้านล่างเรียง () ฟังก์ชั่นที่มีการสับเปลี่ยนฟังก์ชั่นเช่นDurstenfeld

ประการแรกเป็นฟังก์ชัน:

function randPassword(letters, numbers, either) {
  var chars = [
   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", // letters
   "0123456789", // numbers
   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" // either
  ];

  return [letters, numbers, either].map(function(len, i) {
    return Array(len).fill(chars[i]).map(function(x) {
      return x[Math.floor(Math.random() * x.length)];
    }).join('');
  }).concat().join('').split('').sort(function(){
    return 0.5-Math.random();
  }).join('')
}

// invoke like so: randPassword(5,3,2);

เช่นเดียวกับ 2 ซับ (เป็นที่ยอมรับว่าเส้นยาวและน่าเกลียดมาก - และจะไม่เป็น 1 ซับหากคุณใช้ฟังก์ชันสับเปลี่ยนที่เหมาะสมไม่แนะนำ แต่บางครั้งก็สนุกอยู่ดี):

var chars = ["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz","0123456789", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"];
var randPwd = [5,3,2].map(function(len, i) { return Array(len).fill(chars[i]).map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('') }).concat().join('').split('').sort(function(){return 0.5-Math.random()}).join('');

คำตอบที่ดี แต่ตัวพิมพ์ใหญ่ Y จะไม่ปรากฏในรหัสผ่านใด ๆ ที่คุณสร้างขึ้น
Ryan Shillington

1
ขอบคุณ. ฉันใช้ชุดอักขระในคำถาม OP แต่ดูเหมือนว่าจะมีข้อบกพร่อง อัปเดตแล้ว
mwag

คุณบอกว่า "ปลอดภัยกว่าคำตอบที่ยอมรับ / ได้รับการโหวตสูงสุด" คุณช่วยอธิบายเหตุผลให้ละเอียดได้ไหม
BenjaminH

นอกจากนี้การใช้ Math.random () สามารถคาดเดาได้ ดังนั้นสำหรับการสร้างรหัสผ่านควรใช้ฟังก์ชันเช่น window.crypto.getRandomValues
BenjaminH

2
เหตุผลที่มีความปลอดภัยมากขึ้นเนื่องจากรองรับมีจำนวนอักขระที่เป็นไปได้ในเอาต์พุตสูงกว่าการใช้ toString (36) ด้วยความยาวเอาต์พุตคงที่ (เช่น 8) หากคุณมีอักขระสูงสุด 36 ตัวให้เลือกคุณจะมีการเรียงสับเปลี่ยนน้อยกว่าถ้าคุณมี 62 ตัวอักษร (ตามตัวอย่าง) หรือดีกว่า แต่พิมพ์ได้ทั้งหมด 95 ตัว (ascii ) ตัวอักษรหรือหากใช้ Unicode จำนวนความเป็นไปได้ที่สูงขึ้นต่อไบต์
mwag

11

สำหรับคนที่กำลังมองหาสคริปต์ที่ง่ายที่สุด ไม่มีwhile (true)ไม่มีif/elseไม่มีการประกาศ

ฐานในคำตอบ mwag แต่นี้ใช้เป็นที่แข็งแกร่งกว่าแบบสุ่มcrypto.getRandomValuesMath.random

Array(20)
  .fill('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$')
  .map(x => x[Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * x.length)])
  .join('');

ดูสิ่งนี้สำหรับ0xffffffff.

ทางเลือก 1

var generatePassword = (
  length = 20,
  wishlist = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$"
) => Array(length)
      .fill('')
      .map(() => wishlist[Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * wishlist.length)])
      .join('');

console.log(generatePassword());

ทางเลือกที่ 2

var generatePassword = (
  length = 20,
  wishlist = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$'
) =>
  Array.from(crypto.getRandomValues(new Uint32Array(length)))
    .map((x) => wishlist[x % wishlist.length])
    .join('')

console.log(generatePassword())

โหนด js

const crypto = require('crypto')

const generatePassword = (
  length = 20,
  wishlist = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$'
) =>
  Array.from(crypto.randomFillSync(new Uint32Array(length)))
    .map((x) => wishlist[x % wishlist.length])
    .join('')

console.log(generatePassword())

1
นี่ไม่ได้ให้รหัสผ่านที่มีความยาว 20 เสมอกันเนื่องจากออฟเซ็ตที่ไม่ได้กำหนด + 1ส่วนที่ไม่จำเป็นและสามารถถอดออกได้
bryc

จับดี @bryc อัปเดตแล้ว ขอบคุณ.
Ninh Pham

1
วิธีแก้ปัญหาที่เป็นประโยชน์และง่ายดาย ทุกคนที่ต้องการทำเช่นนี้ภายใน NodeJS ก็สามารถแทนที่crypto.getRandomValuesด้วยcrypto.randomFillSync
Rvy Pandey

เพิ่มเวอร์ชัน Node.js ขอบคุณ @Rvy Pandey
Ninh Pham

8

สิ่งนี้ไม่ได้รับการปรับให้เหมาะสมอย่างแน่นอน แต่ควรใช้งานได้

var chars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
var string_length = 8;
var randomstring = '';
var charCount = 0;
var numCount = 0;

for (var i=0; i<string_length; i++) {
    // If random bit is 0, there are less than 3 digits already saved, and there are not already 5 characters saved, generate a numeric value. 
    if((Math.floor(Math.random() * 2) == 0) && numCount < 3 || charCount >= 5) {
        var rnum = Math.floor(Math.random() * 10);
        randomstring += rnum;
        numCount += 1;
    } else {
        // If any of the above criteria fail, go ahead and generate an alpha character from the chars string
        var rnum = Math.floor(Math.random() * chars.length);
        randomstring += chars.substring(rnum,rnum+1);
        charCount += 1;
    }
}

alert(randomstring);

​ ​ ​

นี่คือ jsfiddle สำหรับคุณที่จะทดสอบ: http://jsfiddle.net/sJGW4/3/


1
chars.substring(rnum, rnum+1)ก็เหมือนกับchars.charAt(rnum)
Mad Echet

8

เป็นบันทึก @RobW จำกัด รหัสผ่านไปยังคงที่จำนวนตัวอักษรตามที่เสนอในรูปแบบ OP เป็นความคิดที่ดี แต่ที่แย่กว่านั้นคำตอบที่เสนอรหัสบนพื้นฐานของการMath.randomมี, ดี, ความคิดที่ดีจริงๆ

เริ่มต้น Let 's กับความคิดที่ดี รหัส OP คือการสุ่มเลือกสตริง 8 อักขระจากชุด 62 การ จำกัด สตริงแบบสุ่มให้เหลือ 5 ตัวอักษรและตัวเลข 3 ตัวหมายความว่ารหัสผ่านที่ได้จะมีเอนโทรปี 28.5 บิตที่ดีที่สุด (ตรงข้ามกับศักยภาพของ 47.6 บิต หากข้อ จำกัด การกระจายตัวอักษร 5 ตัวและตัวเลข 3 ตัวถูกลบออก) นั่นไม่ดีมาก แต่ในความเป็นจริงสถานการณ์เลวร้ายยิ่งกว่า ด้านที่ดีที่สุดของรหัสถูกทำลายโดยการใช้Math.randomเป็นวิธีการสร้างเอนโทรปีสำหรับรหัสผ่าน Math.randomเป็นหลอกเครื่องกำเนิดไฟฟ้าจำนวนสุ่ม เนื่องจากลักษณะการกำหนดของเครื่องสร้างตัวเลขสุ่มหลอกเอนโทรปีของรหัสผ่านที่เกิดขึ้นจึงไม่ดีจริงๆการแสดงผลโซลูชันที่นำเสนอดังกล่าวเป็นความคิดที่แย่มาก สมมติว่ารหัสผ่านเหล่านี้ถูกส่งออกไปยังผู้ใช้ปลายทาง (o / w คืออะไร) ฝ่ายตรงข้ามที่ใช้งานอยู่ซึ่งได้รับรหัสผ่านดังกล่าวมีโอกาสที่ดีมากในการคาดเดารหัสผ่านในอนาคตให้กับผู้ใช้รายอื่นและนั่นอาจไม่ใช่เรื่องดี

แต่กลับไปเพียงแค่ความคิดที่ดี Math.randomสมมติกำเนิดหลอกตัวเลขที่แข็งแกร่งจะถูกนำมาใช้แทน ทำไมคุณถึง จำกัด รหัสผ่านไว้ที่ 28.5 บิต? ดังที่ระบุไว้ว่าไม่ค่อยดีนัก โดยสันนิษฐานว่าเป็นตัวอักษร 5 ตัวรูปแบบตัวเลข 3 ตัวเพื่อช่วยผู้ใช้ในการจัดการรหัสผ่านแบบสุ่ม แต่ลองมาดูกันคุณต้องสร้างความสมดุลในการใช้งานที่ง่ายกับมูลค่าการใช้งานและเอนโทรปี 28.5 บิตนั้นไม่คุ้มค่ามากในการป้องกันศัตรู

แต่พอของไม่ดี ขอเสนอเส้นทางข้างหน้า ฉันจะใช้ไลบรารีJavaScript EntropyStringซึ่ง "สร้างสตริงสุ่มที่แข็งแกร่งในการเข้ารหัสของเอนโทรปีที่ระบุจากชุดอักขระต่างๆ" อย่างมีประสิทธิภาพ แทนที่จะใช้อักขระ OP 62 ฉันจะใช้ชุดอักขระที่มี 32 อักขระที่เลือกเพื่อลดการใช้อักขระที่สับสนได้ง่ายหรือการสร้างคำในภาษาอังกฤษ และแทนที่จะใช้ตัวอักษร 5 ตัว 3 รูปแบบ (ซึ่งมีเอนโทรปีน้อยเกินไป) ฉันจะประกาศว่ารหัสผ่านจะมีเอนโทรปี 60 บิต (นี่คือความสมดุลของความง่ายเทียบกับค่า)

import { Entropy, charSet32 } from 'entropy-string'
const random = new Entropy({ bits: 60, charset: charset32 })
const string = random.string()

"Q7LfR8Jn7RDp"

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


ขอบคุณ! โปรดทราบว่าตัวอย่างที่นี่ใช้ไม่ได้อีกต่อไป
Geza Turi

1
ข้อมูลโค้ดได้รับการอัปเดตเป็นเวอร์ชันใหม่กว่าของไลบรารี นอกจากนี้ยังมีตัวอย่างมากมายในไลบรารี README และ GitHub repo
dingo sky

7

ในกรณีที่คุณต้องการรหัสผ่านที่สร้างขึ้นด้วยตัวเลขอย่างน้อย 1 ตัวอักขระตัวพิมพ์ใหญ่ 1 ตัวและอักขระตัวพิมพ์เล็ก 1 ตัว:

function generatePassword(passwordLength) {
  var numberChars = "0123456789";
  var upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  var lowerChars = "abcdefghijklmnopqrstuvwxyz";
  var allChars = numberChars + upperChars + lowerChars;
  var randPasswordArray = Array(passwordLength);
  randPasswordArray[0] = numberChars;
  randPasswordArray[1] = upperChars;
  randPasswordArray[2] = lowerChars;
  randPasswordArray = randPasswordArray.fill(allChars, 3);
  return shuffleArray(randPasswordArray.map(function(x) { return x[Math.floor(Math.random() * x.length)] })).join('');
}

function shuffleArray(array) {
  for (var i = array.length - 1; i > 0; i--) {
    var j = Math.floor(Math.random() * (i + 1));
    var temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
  return array;
}

alert(generatePassword(12));

นี่คือซอถ้าคุณต้องการเล่น / ทดสอบ: http://jsfiddle.net/sJGW4/155/

อุปกรณ์ประกอบภาพถึง @mwag เพื่อให้ฉันเริ่มสร้างสิ่งนี้


1
คุณไม่มีตัวพิมพ์เล็กj: P ไม่งั้นของดีตรงนี้ แก้ไขเล็กน้อยเพื่อให้ตรงกับความต้องการของฉันแม้ว่า
Igor Yavych

6

ฉันได้เขียนสิ่งเล็ก ๆ ที่ได้รับแรงบันดาลใจจากคำตอบของคุณ:

(function(){g=function(){c='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';p='';for(i=0;i<8;i++){p+=c.charAt(Math.floor(Math.random()*62));}return p;};p=g();while(!/[A-Z]/.test(p)||!/[0-9]/.test(p)||!/[a-z]/.test(p)){p=g();}return p;})()

ฟังก์ชันนี้ส่งคืนรหัสผ่านและสามารถใช้ใน bookmarklet เช่น:

javascript:alert(TheCodeOfTheFunction);

3

ฉันไม่แนะนำให้ใช้รหัสผ่านบังคับเนื่องจากมัน จำกัด การรักษาความปลอดภัยของผู้ใช้ แต่อย่างไรก็ตามมีอยู่สองสามวิธีในการดำเนินการ -

วิธี JavaScript แบบดั้งเดิม -

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

ใช้สตริงสุ่ม

ติดตั้งสตริงแบบสุ่ม:

npm install randomstring

ใช้ใน App.js -

var randStr = require('randomstring');

var yourString = randStr.generate(8);

yourStringคุณค่าของรหัสผ่านของคุณจะถูกระงับในตัวแปร

อย่าใช้รหัสผ่านบังคับ!

รหัสผ่านบังคับอาจเป็นอันตรายต่อความปลอดภัยของคุณเนื่องจากรหัสผ่านทั้งหมดจะอยู่ภายใต้ชุดอักขระเดียวกันซึ่งอาจถูกละเมิดได้ง่าย!


3

โอเคถ้าฉันเข้าใจดีว่าคุณกำลังพยายามหารหัสผ่านสตริงแบบสุ่มซึ่งมีตัวอักษร 5 ตัวและตัวเลข 3 ตัวในตำแหน่งแบบสุ่มซึ่งมีความยาว 8 ตัวอักษรและคุณยอมรับตัวอักษร maj และ min คุณสามารถทำได้ด้วยฟังก์ชันต่อไปนี้ :

function randPass(lettersLength,numbersLength) {
    var j, x, i;
    var result           = '';
    var letters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    var numbers       = '0123456789';
    for (i = 0; i < lettersLength; i++ ) {
        result += letters.charAt(Math.floor(Math.random() * letters.length));
    }
    for (i = 0; i < numbersLength; i++ ) {
        result += numbers.charAt(Math.floor(Math.random() * numbers.length));
    }
    result = result.split("");
    for (i = result.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = result[i];
        result[i] = result[j];
        result[j] = x;
    }
    result = result.join("");
    return result
}

function randPass(lettersLength,numbersLength) {
    var j, x, i;
    var result           = '';
    var letters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    var numbers       = '0123456789';
    for (i = 0; i < lettersLength; i++ ) {
        result += letters.charAt(Math.floor(Math.random() * letters.length));
    }
    for (i = 0; i < numbersLength; i++ ) {
        result += numbers.charAt(Math.floor(Math.random() * numbers.length));
    }
    result = result.split("");
    for (i = result.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = result[i];
        result[i] = result[j];
        result[j] = x;
    }
    result = result.join("");
    return result
}
console.log(randPass(5,3))


2
var letters = ['a','b','c','d','e','f','g','h','i','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
    var numbers = [0,1,2,3,4,5,6,7,8,9];
    var randomstring = '';

        for(var i=0;i<5;i++){
            var rlet = Math.floor(Math.random()*letters.length);
            randomstring += letters[rlet];
        }
        for(var i=0;i<3;i++){
            var rnum = Math.floor(Math.random()*numbers.length);
            randomstring += numbers[rnum];
        }
     alert(randomstring);

1

และสุดท้ายโดยไม่ต้องใช้แฮ็กจุดลอยตัว:

function genpasswd(n) {
    // 36 ** 11 > Number.MAX_SAFE_INTEGER
    if (n > 10)
        throw new Error('Too big n for this function');
    var x = "0000000000" + Math.floor(Number.MAX_SAFE_INTEGER * Math.random()).toString(36);
    return x.slice(-n);
}

1

รหัสผ่านที่ปลอดภัยด้วยตัวพิมพ์ด้านบนหนึ่งตัว

let once = false;

    let newPassword = Math.random().toString(36).substr(2, 8).split('').map((char) => {
                    if(!Number(char) && !once){
                        once = true;
                        return char.toUpperCase();
                    }
                    return char;
                }).join('');

    console.log(newPassword)

1

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

const generatePassword = (
  passwordLength = 12,
  passwordChars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
) =>
  [...window.crypto.getRandomValues(new Uint32Array(passwordLength))]
    .map(x => passwordChars[x % passwordChars.length])
    .join('');


1

สร้างบริการสร้างรหัสผ่านที่เรียกว่า PassswordGeneratorService

import { Injectable } from '@angular/core';

@Injectable()
export class PasswordGeneratorService {

  generatePassword(length:number,upper:boolean,numbers:boolean,symbols:boolean) {
    const passwordLength = length || 12;
    const addUpper =  upper;
    const addNumbers =  numbers;
    const addSymbols =  symbols;

    const lowerCharacters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
    const upperCharacters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
    const numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    const symbols = ['!', '?', '@'];

    const getRandom = array => array[Math.floor(Math.random() * array.length)];

    let finalCharacters = '';

    if (addUpper) {
      finalCharacters = finalCharacters.concat(getRandom(upperCharacters));
    }

    if (addNumbers) {
      finalCharacters = finalCharacters.concat(getRandom(numbers));
    }

    if (addSymbols) {
      finalCharacters = finalCharacters.concat(getRandom(symbols));
    }

    for (let i = 1; i < passwordLength - 3; i++) {
      finalCharacters = finalCharacters.concat(getRandom(lowerCharacters));
    }

    return  finalCharacters.split('').sort(() => 0.5 - Math.random()).join('');
  }
}

อย่าลืมเพิ่มบริการในโมดูลที่คุณใช้

@NgModule({
  imports: [
    CommonModule,
    SharedModule,
    CommonModule,
    RouterModule.forChild(routes),
    FormsModule,
    ReactiveFormsModule,
    FlexLayoutModule,
    TranslateModule,
    ExistingUserDialogModule,
    UserDocumentsUploadDialogModule
  ],
  declarations: [
    UserListComponent,
    EditUserDialogComponent,
    UserEditorComponent
  ],
  entryComponents: [
    EditUserDialogComponent
  ],
  providers: [
    AuthService,
    PasswordGeneratorService
  ]
})
export class UsersModule {
}

บนคอนโทรลเลอร์ของคุณให้เพิ่มวิธีการที่เรียกใช้เมธอดสร้างรหัสผ่านภายในบริการและตั้งค่าผลลัพธ์ในฟิลด์รหัสผ่าน

  constructor(
     private passwordGenerator: PasswordGeneratorService,
    )
  get newPassword() {
    return this.password.get('newPassword');
  }
  generatePassword() {
    this.newPassword.setValue(this.passwordGenerator.generatePassword(8,true,true,true));
  }

ฉันเพิ่งถอดฟังก์ชั่นgeneratePasswordและใช้มันไม่จำเป็นต้องมีทั้งคลาส thnx
Biskrem Muhammad

0

มีตัวสร้างสตริงรหัสผ่านแบบสุ่มพร้อมความยาวที่เลือก

let input = document.querySelector("textarea");
let button = document.querySelector("button");
let length = document.querySelector("input");

function generatePassword(n) 
{
	let pwd = "";

  while(!pwd || pwd.length < n)
  {
  	pwd += Math.random().toString(36).slice(-22);
  }
  
  return pwd.substring(0, n);
}

button.addEventListener("click", function()
{
	input.value = generatePassword(length.value);
});
<div>password:</div>
<div><textarea cols="70" rows="10"></textarea></div>
<div>length:</div>
<div><input type="number" value="200"></div>
<br>
<button>gen</button>


0

คุณสามารถใช้วัตถุ window.crypto ที่มีอยู่ในเบราว์เซอร์เวอร์ชันล่าสุดได้ตลอดเวลา

เพียงแค่ต้องการรหัสหนึ่งบรรทัดเพื่อรับหมายเลขสุ่ม:

let n = window.crypto.getRandomValues(new Uint32Array(1))[0];

นอกจากนี้ยังช่วยในการเข้ารหัสและถอดรหัสข้อมูล ข้อมูลเพิ่มเติมได้ที่MDN เว็บเอกสาร - window.crypto


0

var Password = {
 
  _pattern : /[a-zA-Z0-9_\-\+\.]/,
  
  
  _getRandomByte : function()
  {
    // http://caniuse.com/#feat=getrandomvalues
    if(window.crypto && window.crypto.getRandomValues) 
    {
      var result = new Uint8Array(1);
      window.crypto.getRandomValues(result);
      return result[0];
    }
    else if(window.msCrypto && window.msCrypto.getRandomValues) 
    {
      var result = new Uint8Array(1);
      window.msCrypto.getRandomValues(result);
      return result[0];
    }
    else
    {
      return Math.floor(Math.random() * 256);
    }
  },
  
  generate : function(length)
  {
    return Array.apply(null, {'length': length})
      .map(function()
      {
        var result;
        while(true) 
        {
          result = String.fromCharCode(this._getRandomByte());
          if(this._pattern.test(result))
          {
            return result;
          }
        }        
      }, this)
      .join('');  
  }    
    
};
<input type='text' id='p'/><br/>
<input type='button' value ='generate' onclick='document.getElementById("p").value = Password.generate(16)'>


0

รหัสผ่านใด ๆ ที่สร้างด้วย Math.random () เป็นรหัสผ่านที่ไม่ดี

ฟังก์ชันนี้ใช้เวลาของระบบเป็นเมล็ดพันธุ์สำหรับตัวสร้างตัวเลขสุ่ม ใครก็ตามที่ทราบเวลาที่สร้างรหัสผ่านสามารถบังคับรหัสผ่านได้อย่างง่ายดาย

ในเกือบทุกกรณีข้อมูลนี้สามารถใช้ได้อย่างง่ายดายเพียงแค่ใช้คอลัมน์ register_time ในฐานข้อมูลที่ถูกแฮ็กและทดสอบค่าทั้งหมดที่สร้างโดยอัลกอริทึม Math.random () โดยใช้เวลาตั้งแต่ 15 ถึง 0 นาทีก่อนหน้า

รหัสผ่านที่สร้างด้วย Math.random () นั้นไร้ค่าอย่างสิ้นเชิงเพราะเวลาที่ใช้รหัสผ่านครั้งแรกเพียงพอสำหรับการถอดรหัส

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