เหตุใดจึงไม่สามารถอ่านจาก / dev / urandom บน OSX ได้


35

เพื่อนร่วมงานแนะนำให้สร้างคีย์สุ่มผ่านคำสั่งต่อไปนี้:

tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs

มันทำให้ฉันมีข้อผิดพลาด:

tr: ลำดับไบต์ที่ผิดกฎหมาย

ฉันกังวลว่าฉันไม่มี/dev/urandomในระบบของฉัน ฉันลองใช้ googling เพื่อหาวิธีติดตั้งไฟล์นี้ แต่ฉันว่างเปล่า ฉันลองlocate urandomแล้วก็ว่างเปล่า (อันที่จริงแล้วพบหน้าคน แต่ไม่ได้ช่วย)

ฉันจะให้urandomบริการบนระบบ Mac OSX ของฉันได้อย่างไร (สิงโต)


3
การใช้งานที่น่าสนใจของxargs...
sendmoreinfo

คำตอบ:


49

จากข้อผิดพลาดที่คุณได้รับฉันไม่คิดว่า / dev / urandom เป็นปัญหา หากเป็นเช่นนั้นฉันคาดว่าจะมีข้อผิดพลาดเช่น "ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว"

ฉันค้นหาข้อความแสดงข้อผิดพลาดที่คุณได้รับและพบสิ่งนี้ซึ่งดูเหมือนว่าอาจเกี่ยวข้องกับปัญหาของคุณ: http://nerdbynature.de/s9y/2010/04/11/tr-Illegal-byte-sequence

โดยทั่วไประบุสถานที่โดยการเติมtrคำสั่งด้วยLC_CTYPE=C:

LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs

ขอบคุณที่ทำเคล็ดลับแน่นอน ความคิดว่าทำไมฉันไม่สามารถหาurandomหรือrandom? พวกเขา "วิเศษ" พิเศษที่ไม่มีอยู่ในระบบไฟล์จริง? (และฉันขอแนะนำให้แก้ไขเพื่อช่วยลดการเชื่อมโยง -Rot)
Kirk Woll

1
ฉันเชื่อว่าlocateไม่ค้นหาระบบไฟล์ของคุณโดยตรง แต่ควรค้นหาคำค้นของคุณโดยใช้ฐานข้อมูลที่สร้างไว้ล่วงหน้า ฐานข้อมูลนี้มีการกำหนดค่าส่วนใหญ่ให้ละเว้น / dev / และระบบไฟล์ 'พิเศษ' อื่น ๆ
lk-

พอยุติธรรม /devแต่ผมไม่เห็นมันเมื่อฉันมองโดยตรงใน ไปคิด แต่ขอขอบคุณอีกครั้งสำหรับความช่วยเหลือ
Kirk Woll

1
ดูเหมือนจะไม่ทำงานกับ 10.9; ยังคงล้มเหลวด้วยข้อความแสดงข้อผิดพลาดเดียวกัน LC_ALL=Cสิ่งที่ไม่หลอกลวง
Erik Allik

1
โปรดเปลี่ยนลิงก์ไปที่nerdbynature.de/s9y/2010/04/11/tr-Illegal-byte-sequenceเนื่องจากขณะนี้ชี้ไปที่หน้าบล็อกล่าสุดที่ไม่มีtrข้อมูล
Jeroen Wiert Pluimers

11

คุณtrพยายามตีความอินพุตเป็นข้อความในการเข้ารหัส UTF-8 ดังนั้นมันจะบ่นและยกเลิกตามลำดับไบต์แรกซึ่งไม่ถูกต้อง UTF-8 คำนำหน้าtrด้วยLC_ALL=CหรือLC_CTYPE=Cจะส่งออกตัวแปรนั้นไปยังสภาพแวดล้อมของtrจึงเปลี่ยนความคิดของตัวละครในท้องถิ่นที่กำหนดให้มาตรฐาน C คือทุกอย่างเป็นเพียงลำดับของไบต์ทึบแสง

โดยวิธีการที่เป็นลำดับ\)-+ในคำสั่งของคุณโดยเจตนา? ซึ่งรวมถึง*เช่นกันซึ่งคุณรวมไว้แล้ว แต่ไม่รวม-ตัวเองตามที่คุณตั้งใจ ดีกว่าที่จะเขียนหนึ่งในเหล่านี้แทน:

LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()\-+=' < /dev/urandom
LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)\\-+= < /dev/urandom

6

ตามที่คนอื่นระบุว่าปัญหาของคุณไม่ได้/dev/urandomหายไป แต่ใช้trงานได้ดีกับ OS X แทนที่จะยุ่งกับสภาพแวดล้อม varialbes ใช้perlแทนtr:

perl -pe 'binmode(STDIN, ":bytes"); tr/A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+=//dc;' < /dev/urandom | head -c 32; echo

นี่เป็นข้อดีของการพกพาได้ใน OS X, Redhat และ Ubuntu

(ฉันได้ลบไพพ์ไปที่เพื่อxargsแทนที่แม่มดechoเพื่อรับบรรทัดใหม่ที่ส่วนท้ายของเอาต์พุต)


ไม่ช้าก็เร็วผมคาดว่า Perl เพื่อให้binmode ":utf8"มาตรฐานที่จุดแก้ปัญหา Perl ของคุณจะมีปัญหาเดียวกันว่าtrไม่
Mark

แก้ไขข้อกังวลของ Mark โดยการเพิ่ม binmode (STDIN, ": bytes") ในตัวอย่างโค้ด
เทรนตัน

2

ประการแรกคุณต้องการรวม-หรือ*ในรายการอักขระที่ถูกต้องหรือไม่? พารามิเตอร์ที่จะtrรวมถึงลำดับ)-+ซึ่งหมายความว่า "ช่วงไบต์ที่เริ่มต้นด้วย)และลงท้ายด้วยการที่เป็นจริง+)*+

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

ปัญหารุ่นนี้เป็นเรื่องผิดปกติเล็กน้อยที่ใช้สัญลักษณ์ที่แตกต่างกัน 76 แบบ ส่วนใหญ่ต้องการตัวอักษรและตัวเลขดังนั้นหากคุณพอใจกับสัญลักษณ์เพียง 64 การใช้base64ยูทิลิตี้จะลดปริมาณการใช้เอนโทรปีของพูล (หมายเหตุว่า 24 คือ 6/8 ของ 32):

head -c24 < /dev/random | base64

1

การเข้ารหัสอักขระของโลแคลของคุณ (ซึ่งคุณสามารถบอกได้locale charmap) เป็นหลายไบต์ต่ออักขระหนึ่งตัว

ปัจจุบันที่พบบ่อยที่สุดคือ UTF-8 ซึ่งสามารถเข้ารหัสอักขระได้ตั้งแต่ 1 ถึง 4 ไบต์ ลำดับของไบต์ทั้งหมดไม่ใช่อักขระที่ถูกต้องใน UTF-8 อักขระที่ไม่ใช่ ASCII ทุกตัวใน UTF-8 เริ่มต้นด้วยหนึ่งไบต์ที่มีบิตสูงสุดสองชุดและบอกจำนวนไบต์ที่มีบิตสูงสุด (แต่ไม่สูงสุดสอง) ตามมา

/dev/urandomมีกระแสสุ่มของไบต์ trแปลอักขระดังนั้นจึงจำเป็นต้องถอดรหัสไบต์เหล่านั้นเป็นอักขระ อักขระ ASCII เหล่านั้นในช่วงของคุณถูกเข้ารหัสด้วยอักขระหนึ่งตัวใน UTF-8 แต่trยังคงต้องถอดรหัสอักขระทั้งหมด มีอินสแตนซ์การเข้ารหัสหลายไบต์อื่น ๆ ที่อักขระบางตัวที่ไม่ใช่A0x41 ไบต์ (รหัสสำหรับA)

เนื่องจากกระแสข้อมูลแบบสุ่มของไบต์ถูกผูกไว้เพื่อประกอบด้วยลำดับที่ไม่ถูกต้อง (เช่น 0x80 ไบต์ด้วยตัวเองไม่ถูกต้องใน UTF-8 เนื่องจากอักขระที่ไม่ใช่ ASCII ต้องเริ่มต้นด้วยไบต์ที่มากกว่า 0xc1 (0xc0 และ 0xc1 ไม่มีใน UTF-) 8 ตัวอักษร)) ดังนั้นtrกลับมาพร้อมกับข้อผิดพลาดเมื่อเกิดขึ้น

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

สำหรับสิ่งนั้นคุณจะต้องตั้งค่าLC_CTYPEตัวแปรการแปลซึ่งเป็นสิ่งที่ตัดสินใจว่าจะใช้ชุดอักขระใดและblankมีalphaลักษณะอย่างไรคลาสของอักขระประกอบด้วย แต่สำหรับคำจำกัดความของช่วง AZ คุณจะต้องตั้งค่าLC_COLLATEตัวแปร (ตัวแปรที่ตัดสินใจสั่งซื้อสตริง)

Caka POSIXสถานที่เกิดเหตุเป็นหนึ่งในตัวละครที่มีการค้ำประกันเดียวไบต์และอาริโซน่าเป็น ABCDEFGHIJKLMNOPQRSTUVWXYZ คุณสามารถทำได้:

 LC_CTYPE=C LC_COLLATE=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'

(ที่นี่ย้าย-ไปยังจุดสิ้นสุดมิฉะนั้น)-+จะใช้เป็นช่วงเช่นA-Z)

แต่โปรดทราบว่าLC_ALLตัวแปรแทนที่ตัวแปรอื่นLC_*และLANGตัวแปรทั้งหมด ดังนั้นหากLC_ALLมีการกำหนดไว้เป็นอย่างอื่นข้างต้นจะไม่มีผลใด ๆ ดังนั้นคุณสามารถทำได้โดยง่าย:

 LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'

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


0

ตามหน้า man / dev / random น่าจะเพียงพอสำหรับความต้องการของคุณ บางที Apple หยุดสร้าง / dev / urandom เพราะไม่จำเป็น?


ฉันไม่ได้มี/dev/randomอย่างใดอย่างหนึ่ง
Kirk Woll

MacOSX ควรมีทั้ง / dev / random และ / dev / urandom บางที Apple อาจไม่รวมไฟล์พิเศษเหล่านั้นอีกต่อไปแล้วใช่ไหม หรืออาจจะมีเฉพาะในกรณีที่คุณติดตั้ง XCode?
jsbillings

1
FWIW อุปกรณ์ทั้งสองมีอยู่ในเวิร์กสเตชัน Lion อัพเกรดเป็น Mountain Lion ของฉัน ฉันเชื่อว่ามันมีอยู่ใน Lion เช่นกัน โหนดจะแตกต่างกันเช่นกัน (13,0 กับ 13,1)
mrb
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.