芯片资讯
- 发布日期:2023-12-31 08:28 点击次数:169
以前用rand和srand生成过伪随机数,伪随机数的序列是固定的,今天学习生成真正的随机数的生成。
熵池利用/dev/urandom可以生成随机数的值,/dev/urandomLinux下的熵池,所谓熵池就是当前系统下的环境噪音,描述了一个系统的混乱程度,环境噪音由这几个方面组成,如内存的使用,文件的使用量,不同类型的进程数量等等。
利用/dev/urandom可以生成随机数的值,/dev/urandomLinux下的熵池,所谓熵池就是当前系统下的环境噪音,描述了一个系统的混乱程度,环境噪音由这几个方面组成,如内存的使用,文件的使用量,不同类型的进程数量等等。
#include
#include
int main()
{
int randNum = 0;
int fd = 0;
for(int i=0;i5;i++)
{
fd = open("/dev/urandom", O_RDONLY);
read(fd, (char *)&randNum,
EEPROM带电可擦可编程存储器芯片大全 sizeof(int));
close(fd);
printf("randNum is %dn",
电子元器件PDF资料大全 randNum);
}
return 0;
}
运行结果:
mapan@mapan-virtual-machine:~/c++$ ./a.out randNum is 94961710 randNum is -523780773 randNum is 1542169420 randNum is -1632410867
每次打印的5个随机数都不一样,芯片交易网IC交易网其实它的随机性也不太好。雪花算法生成的数的随机性很好, ATMEGA系列ATMEL芯片COM通常在分布式系统中生成唯一ID。
雪花算法SnowFlake算法产生的ID是一个64位的整型, CMOS图像传感器集成电路芯片结构如下(每一部分用“-”符号分隔): 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 00000000000
1位标识部分,电子元器件PDF资料大全在java中由于long的最高位是符号位,正数是0,负数是1,一般生成的ID为正数,所以为0;
41位时间戳部分,这个是毫秒级的时间,一般实现上不会存储当前的时间戳,而是时间戳的差值(当前时间-固定的开始时间),这样可以使产生的ID从更小值开始;41位的时间戳可以使用69年,(1L
10位节点部分,Twitter实现中使用前5位作为数据中心标识,后5位作为机器标识,可以部署1024个节点;
12位序列号部分,支持同一毫秒内同一个节点可以生成4096个ID;
/*
snowflake
ID 生成策略
毫秒级时间41位+机器ID 10位+毫秒内序列12位。
0 41 51 64 +-----------+------+------+ |time |pc |inc | +-----------+------+------+
前41bits是以微秒为单位的timestamp。
接着10bits是事先配置好的机器ID。
最后12bits是累加计数器。
macheine id(10bits)标明最多只能有1024台机器同时产生ID,sequence number(12bits)也标明1台机器1ms中最多产生4096个ID, *
注意点,因为使用到位移运算,所以需要64位操作系统,不然生成的ID会有可能不正确
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct globle
{
int global_int:12;
uint64_t last_stamp;
int workid;
int seqid;
};
void set_workid(int workid);
pid_t gettid( void );
uint64_t get_curr_ms();
uint64_t wait_next_ms(uint64_t lastStamp);
int atomic_incr(int id);
uint64_t get_unique_id();
#include "snowflake.h"
struct globle g_info;
#define sequenceMask (-1L ^ (-1L //L表示long型 4095
void set_workid(int workid)
{
g_info.workid = workid;
}
pid_t gettid( void )//获取线程ID
{
return syscall( __NR_gettid );
}
uint64_t get_curr_ms() //获取毫秒
{
struct timeval time_now;
gettimeofday(&time_now,NULL);
uint64_t ms_time =time_now.tv_sec*1000+time_now.tv_usec/1000;
return ms_time;
}
uint64_t wait_next_ms(uint64_t lastStamp)
{
uint64_t cur = 0;
do {
cur = get_curr_ms();
} while (cur return cur;
}
int atomic_incr(int id)//累加
{
__sync_add_and_fetch(&id, 1);
return id;
}
uint64_t get_unique_id()
{
uint64_t uniqueId=0;
uint64_t nowtime = get_curr_ms();//获取当前毫秒数
uniqueId = nowtime 22; //填补时间戳部分
//0x3ff 1023,二进制对应11 1111 1111
//100的二进制0000 0000 0000 0000 0000 0000 0110 0100
//先执行移位
uniqueId |= (g_info.workid & 0x3ff) 12; //填补节点部分
if (nowtime perror("error");
exit(-1);
}
if (nowtime == g_info.last_stamp)
{
//4095的二进制0000 1111 1111 1111 [long型]
g_info.seqid = atomic_incr(g_info.seqid) & sequenceMask;
if (g_info.seqid == 0) //seqid=0防止冲突,修改时间
{
nowtime = wait_next_ms(g_info.last_stamp);//获取大于当前时间的time
}
}
else
{
g_info.seqid = 0;
}
g_info.last_stamp = nowtime;
uniqueId |= g_info.seqid;//填补序列号部分
return uniqueId;
}
int main()
{
set_workid(100);
int i;
for(i=0;i10;i++)
{
uint64_t unquie = get_unique_id();
printf("pthread_id:%u, id [%llu]n",gettid(),unquie);
}
return;
}
运行结果:
mapan@mapan-virtual-machine:~/c++$ ./a.out pthread_id:4970, id [6595660141600063488] pthread_id:4970, id [6595660141600063489] pthread_id:4970, id [6595660141600063490] pthread_id:4970, id [6595660141600063491] pthread_id:4970, id [6595660141600063492]
- 电子电路元器件套装与原理图解析:芯片分销商模式如何赋能电子设计2025-05-06
- 芯片的市场应用和前景如何?2024-03-12
- 芯片的成本如何计算和控制2024-03-11
- 芯片的可靠性如何评估?2024-03-07
- 芯片的频率特性如何?2024-02-27
- 如何成为一名合格的电子元器件工程师2024-02-21
