关于<ctime>和<cstdlib>

本文介绍了如何在C++中使用ctime和cstdlib头文件来生成随机数。通过srand()和rand()函数结合时间作为种子,确保每次运行程序时都能得到不同的随机数序列。

    因为自己完全是一个菜鸟级的,所以从最基础的学起,把所遇到的不懂得地方都写下来,希望对自己对别人都能有所帮助。。。

    time.h和stdlib.h是C语言中的头文件。ctime 是C里面的用在C++的时间函数头文件,cstdlib是C里面用在C++ 的一些库函数文件,在C++里Include C的头文件,就需要在原来的.h文件前加个c,并去掉.h,那两个头文件对应c中的stdlib.h和time.h .

    通常我们要产生随即数时,往往会用到这两个头文件,如下代码:

 #include<iostream>
 #include<cstdlib>
 #include <ctime>
 using namespace std;

void main()
{

   srand (time(0));   
   int a=rand()%100;
   cout << a;

}

函数srand()和rand()包含在cstdlib中,time()包含在ctime中,srand()是给rand()一个种子值,time(0)则是取系统的当前值,为了每次调用rand()函数时产生一系列不同的随机数 ,对于srand (time(NULL));    是利用时间设置随机种子,

#include &lt;iostream> #include &lt;cstring> #include &lt;ctime&gt; #include &lt;cstdlib&gt; using namespace std; #define WORD_SIZE 32 #define NUM_WORDS 64 // 2048位 = 64 * 32位 #define MONTGOMERY_R (1ULL &lt;&lt; (WORD_SIZE * NUM_WORDS)) // R = 2^(2048) struct BigNum { uint32_t words[NUM_WORDS]; BigNum() { memset(words, 0, sizeof(words)); } BigNum(uint64_t val) { memset(words, 0, sizeof(words)); words[0] = val & 0xFFFFFFFF; if (NUM_WORDS > 1) { words[1] = val >> 32; } } void print() const { for (int i = NUM_WORDS - 1; i >= 0; i--) { printf("%08x", words[i]); } cout &lt;&lt; endl; } }; struct ExtendedBigNum { uint32_t words[2 * NUM_WORDS]; ExtendedBigNum() { memset(words, 0, sizeof(words)); } ExtendedBigNum(const BigNum& a) { memset(words, 0, sizeof(words)); for (int i = 0; i &lt; NUM_WORDS; i++) { words[i] = a.words[i]; } } BigNum to_bignum() const { BigNum result; for (int i = 0; i &lt; NUM_WORDS; i++) { result.words[i] = words[i]; } return result; } }; inline uint32_t ct_select_word(uint32_t a, uint32_t b, uint32_t selector) { return (a & ~selector) | (b & selector); } BigNum ct_select_bignum(const BigNum& a, const BigNum& b, uint32_t selector) { BigNum result; uint32_t mask = selector; for (int i = 0; i &lt; NUM_WORDS; i++) { result.words[i] = ct_select_word(a.words[i], b.words[i], mask); } return result; } uint32_t ct_compare(const BigNum& a, const BigNum& b) { uint32_t gt = 0, lt = 0; for (int i = NUM_WORDS - 1; i >= 0; i--) { uint32_t a_val = a.words[i]; uint32_t b_val = b.words[i]; gt |= ((a_val > b_val) & ~lt) & ~gt; lt |= ((a_val &lt; b_val) & ~gt) & ~lt; } return ct_select_word(0, ct_select_word(1, 2, gt), lt | gt); } BigNum ct_add(const BigNum& a, const BigNum& b) { BigNum result; uint64_t carry = 0; for (int i = 0; i &lt; NUM_WORDS; i++) { uint64_t sum = (uint64_t)a.words[i] + b.words[i] + carry; result.words[i] = sum & 0xFFFFFFFF; carry = sum >> WORD_SIZE; } return result; } BigNum ct_sub(const BigNum& a, const BigNum& b) { BigNum result; uint64_t borrow = 0; for (int i = 0; i &lt; NUM_WORDS; i++) { uint64_t diff = (uint64_t)a.words[i] - b.words[i] - borrow; result.words[i] = diff & 0xFFFFFFFF; borrow = (diff >> WORD_SIZE) & 1; } return result; } BigNum multiply(const BigNum& a, const BigNum& b) { BigNum result; uint64_t temp[2 * NUM_WORDS] = { 0 }; for (int i = 0; i &lt; NUM_WORDS; i++) { uint64_t carry = 0; for (int j = 0; j &lt; NUM_WORDS; j++) { uint64_t product = (uint64_t)a.words[i] * b.words[j] + temp[i + j] + carry; temp[i + j] = product & 0xFFFFFFFF; carry = product >> WORD_SIZE; } if (i + NUM_WORDS &lt; 2 * NUM_WORDS) { temp[i + NUM_WORDS] = carry; } } for (int i = 0; i &lt; NUM_WORDS; i++) { result.words[i] = temp[i]; } return result; } ExtendedBigNum multiply_extended(const BigNum& a, const BigNum& b) { ExtendedBigNum result; for (int i = 0; i &lt; NUM_WORDS; i++) { uint64_t carry = 0; for (int j = 0; j &lt; NUM_WORDS; j++) { uint64_t product = (uint64_t)a.words[i] * b.words[j] + result.words[i + j] + carry; result.words[i + j] = product & 0xFFFFFFFF; carry = product >> WORD_SIZE; } if (i + NUM_WORDS &lt; 2 * NUM_WORDS) { result.words[i + NUM_WORDS] = carry; } } return result; } BigNum barrett_precompute(const BigNum& modulus) { BigNum mu; BigNum two_pow_2k; two_pow_2k.words[2 * NUM_WORDS / WORD_SIZE - 1] = 1ULL &lt;&lt; (2 * NUM_WORDS * WORD_SIZE % WORD_SIZE); // 简化:这里我们使用一个近似值 // 实际实现需要完整的除法算法 mu = BigNum(1ULL &lt;&lt; 32); // 简化实现 return mu; } BigNum barrett_reduce(const BigNum& a, const BigNum& modulus, const BigNum& mu) { // 简化实现,实际需要完整Barrett算法 BigNum result = a; while (ct_compare(result, modulus) == 1) { result = ct_sub(result, modulus); } return result; } // 蒙哥马利乘法预计算参数 BigNum montgomery_precompute(const BigNum& modulus) { BigNum n_prime; // 简化实现,实际需要扩展欧几里得算法 n_prime = BigNum(1); return n_prime; } // 蒙哥马利乘法 BigNum montgomery_multiply(const BigNum& a, const BigNum& b, const BigNum& modulus, const BigNum& n_prime) { ExtendedBigNum t_ext = multiply_extended(a, b); BigNum t = t_ext.to_bignum(); ExtendedBigNum m_ext = multiply_extended(t, n_prime); BigNum m; for (int i = 0; i &lt; NUM_WORDS; i++) { m.words[i] = m_ext.words[i]; } ExtendedBigNum m_times_n_ext = multiply_extended(m, modulus); ExtendedBigNum result_ext; uint64_t carry = 0; for (int i = 0; i &lt; 2 * NUM_WORDS; i++) { uint64_t sum = (uint64_t)t_ext.words[i] + m_times_n_ext.words[i] + carry; result_ext.words[i] = sum & 0xFFFFFFFF; carry = sum >> WORD_SIZE; } BigNum result; for (int i = 0; i &lt; NUM_WORDS; i++) { result.words[i] = result_ext.words[i + NUM_WORDS]; } uint32_t cmp = ct_compare(result, modulus); uint32_t selector = (cmp == 1) ? 0xFFFFFFFF : 0; result = ct_select_bignum(result, ct_sub(result, modulus), selector); return result; } // 转蒙哥马利形式 BigNum to_montgomery(const BigNum& a, const BigNum& modulus, const BigNum& n_prime) { BigNum r_squared; r_squared.words[2 * NUM_WORDS / WORD_SIZE - 1] = 1ULL &lt;&lt; (2 * NUM_WORDS * WORD_SIZE % WORD_SIZE); r_squared = barrett_reduce(r_squared, modulus, barrett_precompute(modulus)); return montgomery_multiply(a, r_squared, modulus, n_prime); } // 转普通形式 BigNum from_montgomery(const BigNum& a_mont, const BigNum& modulus, const BigNum& n_prime) { // 乘以1,即计算 a_mont * 1 * R^{-1} mod N BigNum one; one.words[0] = 1; return montgomery_multiply(a_mont, one, modulus, n_prime); } // 蒙哥马利幂运算 BigNum montgomery_power(const BigNum& base, const BigNum& exponent, const BigNum& modulus, const BigNum& n_prime) { BigNum base_mont = to_montgomery(base, modulus, n_prime); BigNum r0, r1; r0 = to_montgomery(BigNum(1), modulus, n_prime); r1 = base_mont; // 从最高位开始处理指数 for (int i = NUM_WORDS * WORD_SIZE - 1; i >= 0; i--) { int word_idx = i / WORD_SIZE; int bit_idx = i % WORD_SIZE; uint32_t bit = (exponent.words[word_idx] >> bit_idx) & 1; uint32_t selector = bit ? 0xFFFFFFFF : 0; BigNum temp_r0 = montgomery_multiply(r0, r1, modulus, n_prime); BigNum temp_r1 = montgomery_multiply(r1, r1, modulus, n_prime); BigNum r0_squared = montgomery_multiply(r0, r0, modulus, n_prime); r0 = ct_select_bignum(r0_squared, temp_r0, selector); r1 = ct_select_bignum(temp_r0, temp_r1, selector); } return from_montgomery(r0, modulus, n_prime); } void rsa_key_gen(BigNum& n, BigNum& e, BigNum& d) { // 在实际实现中,这里需要生成大素数pq // 简化:使用预定义的值 BigNum p(61); BigNum q(53); n = multiply(p, q); BigNum phi_n = multiply(BigNum(60), BigNum(52)); e = BigNum(17);/ d = BigNum(2753); } // RSA加密 BigNum rsa_encrypt(const BigNum& message, const BigNum& e, const BigNum& n) { BigNum n_prime = montgomery_precompute(n); return montgomery_power(message, e, n, n_prime); } // RSA解密 BigNum rsa_decrypt(const BigNum& ciphertext, const BigNum& d, const BigNum& n) { BigNum n_prime = montgomery_precompute(n); return montgomery_power(ciphertext, d, n, n_prime); } int main() { BigNum n, e, d; rsa_key_gen(n, e, d); cout &lt;&lt; "n: "; n.print(); cout &lt;&lt; "e: "; e.print(); cout &lt;&lt; "d: "; d.print(); // 明文 BigNum message(42); cout &lt;&lt; "明文:"; message.print(); // 加密 BigNum ciphertext = rsa_encrypt(message, e, n); cout &lt;&lt; "密文:"; ciphertext.print(); // 解密 BigNum decrypted = rsa_decrypt(ciphertext, d, n); cout &lt;&lt; "解密:"; decrypted.print(); return 0; } 上面的代码尝试完成使用Montgomery’s ladder算法的RSA实现,请修改正确、补充完整,要求:大数要至少2048位,用数组表示,不要使用openssl、NTL等库,乘法模逆运算使用蒙哥马利乘法Barrett归约法
最新发布
09-21
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值