ฉันกำลังมองหาวิธีสร้างตัวเลขสุ่มขนาดใหญ่ตามลำดับ 2^64 ใน C... (100000000 - 999999999) เพื่อใช้ในอัลกอริธึมการเข้ารหัสคีย์สาธารณะ (as p และ q)
ฉันไม่ต้องการสร้างตัวเลขที่เล็กกว่า 2^64 (นั่นคือ น้อยกว่า 100000000)
มีอะไรที่สามารถช่วยฉันทำเช่นนี้?
ฉันกำลังมองหาวิธีสร้างตัวเลขสุ่มขนาดใหญ่ตามลำดับ 2^64 ใน C... (100000000 - 999999999) เพื่อใช้ในอัลกอริธึมการเข้ารหัสคีย์สาธารณะ (as p และ q)
ฉันไม่ต้องการสร้างตัวเลขที่เล็กกว่า 2^64 (นั่นคือ น้อยกว่า 100000000)
มีอะไรที่สามารถช่วยฉันทำเช่นนี้?
Random() ส่งคืนค่ายาวซึ่งในระบบ 64 บิตควรเป็น 64 บิต หากคุณใช้ระบบ 32 บิต คุณสามารถทำสิ่งต่อไปนี้:
#include <inttypes.h>
uint64_t num;
/* add code to seed random number generator */
num = rand();
num = (num << 32) | rand();
// enforce limits of value between 100000000 and 999999999
num = (num % (999999999 - 100000000)) + 100000000;
อีกทางหนึ่งบนระบบ NIX คุณสามารถอ่าน /dev/random ลงในบัฟเฟอร์ของคุณ:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <inttypes.h>
int fd;
uint64_t num;
if ((fd = open("/dev/random", O_RDONLY) == -1)
{
/* handle error */
};
read(fd, &num, 8);
close(fd);
// enforce limits of value between 100000000 and 999999999
num = (num % (999999999 - 100000000)) + 100000000;
A
rand()
ถูกจำกัดด้วย RAND_MAX
ซึ่งไม่จำเป็น 2^32
และคุณยังต้องการบางสิ่งเพื่อส่งต่อไปยัง srand()
/dev/random
ฟังก์ชันการทำงานยังมีให้บริการบน แพลตฟอร์มอื่นๆ
- person Piotr Praszmo; 27.10.2011
num = (num % (999999999 - 100000000)) + 100000000;
เพื่อสร้างตัวเลขสุ่มของขีดจำกัดล่าง 100000000 และขีดจำกัดบน 999999999
- person David M. Syzdek; 28.10.2011
RAND_MAX
คือ 2^31
ไม่ใช่ 2^32
- person Chiel ten Brinke; 26.12.2014
u32
มีการกระจายอย่างสม่ำเสมอ แล้วจำนวนรวมดังกล่าวจะเป็น u64 = (u32 << 32) | u32
ด้วยหรือไม่
- person this; 02.07.2015
num = (num << 32) | rand();
น่าจะอ่อนแอหากคุณใช้ 32 บิต ดังนั้น RAND_MAX
น่าจะเป็น 2^31-1 หรือน้อยกว่ามาก จากนั้น num = (num << 32) | rand();
จะเสมอสร้าง raw num
โดยมีบิตบางส่วนถูกล้างในตำแหน่งเดียวกัน num % (999999999 - 100000000)
ช่วยกระจายปัญหานั้นไปรอบๆ โดยที่ยังขาดการกระจายแบบเดียวกันอีกด้วย
- person chux - Reinstate Monica; 16.08.2018
คุณสามารถรวมจำนวนเต็มสุ่ม 4 ไบต์สองตัวเพื่อสร้างจำนวน 8 ไบต์:
#include <stdint.h>
...
uint64_t random =
(((uint64_t) rand() << 0) & 0x00000000FFFFFFFFull) |
(((uint64_t) rand() << 32) & 0xFFFFFFFF00000000ull);
เนื่องจาก rand
ส่งคืน int
และ sizeof(int) >= 4
บนแพลตฟอร์มสมัยใหม่เกือบทุกแห่ง โค้ดนี้จึงควรใช้งานได้ ฉันได้เพิ่ม << 0
เพื่อให้เจตนาชัดเจนยิ่งขึ้น
การมาสก์ด้วย 0x00000000FFFFFFFF
และ 0xFFFFFFFF00000000
เป็นการป้องกันการทับซ้อนกันของบิตในตัวเลขทั้งสองในกรณี sizeof(int) > 4
แก้ไข
เนื่องจาก @Banthar แสดงความคิดเห็นว่า RAND_MAX
ไม่จำเป็นต้อง 2 ^ 32
และฉันคิดว่ารับประกันได้ว่าจะมีอย่างน้อย 2 ^ 16
คุณสามารถรวมตัวเลข 2 ไบต์สี่ตัวเข้าด้วยกันเพื่อให้แน่ใจ:
uint64_t random =
(((uint64_t) rand() << 0) & 0x000000000000FFFFull) |
(((uint64_t) rand() << 16) & 0x00000000FFFF0000ull) |
(((uint64_t) rand() << 32) & 0x0000FFFF00000000ull) |
(((uint64_t) rand() << 48) & 0xFFFF000000000000ull);
^
เพื่อรวมตัวเลขแทน |
คุณไม่จำเป็นต้องกังวลเกี่ยวกับการมาสก์
- person caf; 28.10.2011
RAND_MAX
ไม่น่าจะเป็นไปได้มากที่จะเป็น 2 ^ 32
อาจจะเป็น (2 ^ 32) - 1
แต่ถึงอย่างนั้นก็เป็นเรื่องแปลก มีแนวโน้มว่าจะเหมือนกับ INT_MAX
ซึ่งมีค่าร่วมคือ (2 ^ 31) - 1
หรือ (2 ^ 15) - 1
C ระบุ RAND_MAX
ให้มีอย่างน้อย (2^15) - 1
ไม่ใช่ 2 ^ 16
- person chux - Reinstate Monica; 16.08.2018
คุณกำลังมองหา PRNG ที่มีการเข้ารหัสที่แข็งแกร่ง เช่น openssl/rand
: http://www.openssl.org/docs/crypto/rand.html
rand()
สำหรับสิ่งนี้เป็นช่องโหว่ด้านความปลอดภัย (การทำนายผลลัพธ์ของ rand()
นั้นไม่ได้ท้าทายมากนัก)
- person Frank Farmer; 28.10.2011
ฉันรู้ว่าฉันอาจจะโดน b____ ตบโดย OliCharlesworth แต่ใช้ rand() ด้วยสเกลและออฟเซ็ต มันอยู่ใน stdlib.h เพื่อให้ครอบคลุมทั้งช่วง คุณควรเพิ่มมันลงใน rand() ที่เล็กกว่าอีกอันเพื่อเติมเต็มช่องว่างในการแมป
คุณสามารถสร้างตัวเลขขนาดใหญ่ L
จากจำนวนที่น้อยกว่าได้ (เช่น A
& B
) เช่น L = (2^ n)*A + B
โดยที่ ^ หมายถึงการยกกำลัง และ n
คือจำนวนเต็มคงที่ (เช่น 32) จากนั้นคุณโค้ด 1<<n
(เลื่อนไปทางซ้ายระดับบิต) สำหรับการดำเนินการยกกำลัง 2
ดังนั้นคุณสามารถสร้างตัวเลขสุ่มขนาดเล็กจำนวนมากโดยการสุ่มได้
L, n, A, and b
หมายถึงอะไร? คุณช่วยอธิบายหน่อยได้ไหม?
- person Ameen; 06.12.2014
u32
มีการกระจายอย่างสม่ำเสมอ แล้วจำนวนรวมดังกล่าวจะเป็น u64 = (u32 << 32) | u32
ด้วยหรือไม่
- person this; 02.07.2015
L = (2^ n)*A + B
จะเป็นปัญหาหากช่วงของ B
ไม่ใช่ [0...(2^ n)-1] ควรใช้ L = (2^ n)*A ^ B
หากช่วง B
กว้างขึ้น (และยังคงเป็นกำลังของ 2) ดีที่สุดคือ L = (max_possible_value_of_B + (type_of_L)1) *A + B
- person chux - Reinstate Monica; 16.08.2018
หรือคุณสามารถใช้ตัวสร้างตัวเลขสุ่มสองตัวที่มีเมล็ดแบบอิสระและรวมหมายเลขเอาต์พุตไว้ด้วยกันตามที่แนะนำ ขึ้นอยู่กับว่าคุณต้องการ RNG จำนวน 64 บิตที่มีจุดในช่วง 2^64 หรือไม่ เพียงอย่าใช้การเรียกเริ่มต้นที่ขึ้นอยู่กับเวลา เพราะคุณจะได้รับเมล็ดพันธุ์ที่เหมือนกันสำหรับเครื่องกำเนิดแต่ละตัว มาถูกทางก็ไม่รู้...