C该程序生成一个唯一的序列号

        在实际的软件开发项目,通常,它包括产生一唯一的序列号。在本文中,一个切实可行的方案,例如,它引入了一个唯一的序列号生成过程。

        本文生成的序列号的样式为:MMDDHHMINSS_XXXXXX。

 

        程序例如以下:

/**********************************************************************
* 版权全部 (C)2014, Zhou Zhaoxiong。
*
* 文件名: SerialNo.c
* 文件标识: 无
* 内容摘要: 用于演示序列号的创建方法
* 其他说明: 无
* 当前版本号: V1.0
* 作        者: 周兆熊
* 完毕日期: 20140603
*
* 改动记录1:// 改动历史记录, 包含改动日期、版本号号、改动人及改动内容
* 改动日期: 20140603
* 版 本 号: V1.0
* 修 改 人: Zhou Zhaoxiong
* 改动内容: 创建
**********************************************************************/

#include <afxinet.h>

// 数据类型
typedef unsigned char       UINT8;
typedef unsigned char       UINT16;
typedef unsigned int           UINT32;
typedef signed   int             INT32;


// 时间信息结构体
typedef struct
{
 UINT8   second;        /* 0-59 */
 UINT8   minute;         /* 0-59 */
 UINT8   hour;             /* 0-23 */
 UINT8   day;              /* 1-31 */
 UINT8   month;           /* 1-12 */
 UINT16  year;             /* 1994-2099 */
 UINT8   week;             /* 1-7 */
 UINT8   Count10ms;  /* 0-99 */
} ClockStruc;


// 函数声明
void  GetCurTime(ClockStruc *pCurrentTime);                           // 获取当前时间
INT32 CreateSerial(UINT8 *pSerialID, UINT32 iSerialSize);     // 创建序列号
INT32 main(void);                                                                             // 主函数


/**********************************************************************
* 功能描写叙述: 获取当前时间                                            
* 输入參数: 无                                                      
* 输出參数: pCurrentTime-当前时间结构体                             
* 返 回 值: 无                                                      
* 其他说明: 无                                                      
* 改动日期      版本号号      改动人          改动内容                 
* ----------------------------------------------------------------------------
* 20140603       V1.0    Zhou Zhaoxiong       创建                   
**********************************************************************/
void GetCurTime(ClockStruc *pCurrentTime)
{
    SYSTEMTIME tCurrentTime;

    GetLocalTime(&tCurrentTime);

    pCurrentTime->month     = (UINT8)tCurrentTime.wMonth;
    pCurrentTime->day       = (UINT8)tCurrentTime.wDay;
    pCurrentTime->hour      = (UINT8)tCurrentTime.wHour;
    pCurrentTime->minute    = (UINT8)tCurrentTime.wMinute;
    pCurrentTime->second    = (UINT8)tCurrentTime.wSecond;
    pCurrentTime->week      = (UINT8)tCurrentTime.wDayOfWeek;
    if (pCurrentTime->week == 0)         // 表示星期天
    {
        pCurrentTime->week = 7;
    }
}


/**********************************************************************
* 功能描写叙述: 创建序列号
* 输入參数: iSerialSize: 序列号长度
* 输出參数: pSerialID: 序列号
* 返 回 值: 0-成功  -1-失败
* 其他说明: 序列号的样式: MMDDHHMINSS_XXXXXX
* 改动日期          版本号号           改动人         改动内容
* --------------------------------------------------------------
* 20140603           V1.0         Zhou Zhaoxiong      创建
***********************************************************************/
INT32 CreateSerial(UINT8 *pSerialID, UINT32 iSerialSize)
{
    ClockStruc    tClock   = {0};
    static UINT32 iTailNum = 0;
   
    if (NULL == pSerialID)
    {
        printf("CreateSerial: input parameter is NULL.\n");
        return -1;
    }

    GetCurTime(&tClock);


    _snprintf((char *)pSerialID, iSerialSize, "%02d%02d%02d%02d%02d_%06d",
             tClock.month, tClock.day, tClock.hour, tClock.minute, tClock.second, iTailNum);


    iTailNum ++;
    if (iTailNum > 999999)
    {
        iTailNum = 0;
    }

    return 0;
}


/****************************************************************
* 功能描写叙述:  主函数                                            
* 输入參数:  无                                                
* 输出參数:  无                                                
* 返 回 值: 0-运行成功  -1-运行失败                           
* 其他说明:  无                                                
* 改动日期        版本号号        改动人        改动内容
* ------------------------------------------------------------------------
* 20140603         V1.0     Zhou Zhaoxiong     创建
****************************************************************/
INT32 main(void)
{
    UINT32 iLoopFlag      = 0;      // 该变量用于表示循环标志
    INT32  iRetValue      = 0;        // 该变量用于表示调用CreateSerial函数返回的值
    UINT8  szSerialID[50] = {0};    // 该变量用于存放生成的序列号
   
    // 生成10个序列号, 并打印出来
    for (iLoopFlag = 0; iLoopFlag < 10; iLoopFlag ++)
    {
        iRetValue = CreateSerial(szSerialID, sizeof(szSerialID));
        if (iRetValue != 0)
        {
            printf("exec CreateSerial failed.\n");
            return -1;
        }
       
        printf("第%d个序列号为: %s\n", iLoopFlag + 1, szSerialID);
    }

    return 0;
}

 

        程序运行的结果例如以下图所看到的:

 

(本人微博: http://weibo.com/zhouzxi?topnav=1&wvr=5,我们聊天号码:245924426。欢迎关注!

)

版权声明:本文博客原创文章,博客,未经同意,不得转载。

### 回答1: 雪花算法(Snowflake)是一种可以生成唯一ID的算法,通常用于分布式系统中,以确保生成的ID在整个系统中是唯一的。下面是使用Java实现雪花算法生成ID的示例代码: ``` public class SnowflakeIdGenerator { private final long twepoch = 1288834974657L; private final long workerIdBits = 5L; private final long datacenterIdBits = 5L; private final long maxWorkerId = -1L ^ (-1L << workerIdBits); private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); private final long sequenceBits = 12L; private final long workerIdShift = sequenceBits; private final long datacenterIdShift = sequenceBits + workerIdBits; private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; private final long sequenceMask = -1L ^ (-1L << sequenceBits); private long workerId; private long datacenterId; private long lastTimestamp = -1L; private long sequence = 0L; public SnowflakeIdGenerator(long workerId, long datacenterId) { if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format("Worker ID can't be greater than %d or less than 0", maxWorkerId)); } if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new IllegalArgumentException(String.format("Datacenter ID can't be greater than %d or less than 0", maxDatacenterId)); } this.workerId = workerId; this.datacenterId = datacenterId; } public synchronized long nextId() { long timestamp = timeGen(); if (timestamp < lastTimestamp) { throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); } if (lastTimestamp == timestamp) { sequence = (sequence + 1) & sequenceMask; if (sequence == 0) { timestamp = tilNextMillis(lastTimestamp); } } else { sequence = 0L; } lastTimestamp = timestamp; return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence; } private long tilNextMillis(long lastTimestamp) { long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; } private long timeGen() { return System.currentTimeMillis(); } } ``` 使用示例: ``` SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1, 1); long id = idGenerator.nextId(); System.out.println(id); ``` 在这个例子中,我们创建了一个SnowflakeIdGenerator类来生成ID。构造函数需要传入workerId和datacenterId两个参数,用来标识生成ID的工作机器和数据中心。nextId()方法生成一个唯一的ID,具体实现如下: 1. 获取当前的时间戳,如果小于上一次生成ID的时间戳,抛出异常; 2. 如果和上一次生成ID的时间戳相同,则 ### 回答2: 雪花算法是一种用于生成全局唯一ID的算法,由Twitter开发并在分布式系统中广泛应用。下面将用Java语言来实现一个简单的雪花算法生成ID的方法。 首先,我们需要定义一些参数来表示雪花算法中的各个部分。如下所示: private long workerId; // 机器ID private long datacenterId; // 数据中心ID private long sequence = 0L; // 序列号 private long twepoch = 1288834974657L; // 设置起始时间戳,当前为Snowflake算法第一次使用的时间 接下来,我们需要在方法中实现生成ID的逻辑。具体步骤如下: 1. 获取当前时间戳timestamp。 2. 如果当前时间小于上一次生成ID的时间戳lastTimestamp,则说明系统时间出现了回拨的情况,需要等待直到时间追上lastTimestamp,避免产生重复的ID。 3. 如果当前时间等于lastTimestamp,则在sequence序列号上自增1。 4. 如果sequence序列号大于等于4096(或其他您所需的最大序列号),则需要等待下一个毫秒再生成ID。 5. 更新lastTimestamp为当前时间戳。 6. 生成ID,根据算法将各个部分的值进行位运算和位移操作。 7. 返回生成的ID。 下面是完整的Java代码示例实现: ``` public class SnowflakeIdGenerator { private long workerId; private long datacenterId; private long sequence = 0L; private long twepoch = 1288834974657L; // 构造方法 public SnowflakeIdGenerator(long workerId, long datacenterId) { this.workerId = workerId; this.datacenterId = datacenterId; } public synchronized long generateId() { long timestamp = System.currentTimeMillis(); if (timestamp < lastTimestamp) { throw new RuntimeException("Clock moved backwards. Refusing to generate id for " + (lastTimestamp - timestamp) + " milliseconds"); } if (timestamp == lastTimestamp) { sequence = (sequence + 1) & 4095; if (sequence == 0) { timestamp = tilNextMillis(lastTimestamp); } } else { sequence = 0L; } lastTimestamp = timestamp; return ((timestamp - twepoch) << 22) | (datacenterId << 17) | (workerId << 12) | sequence; } private long tilNextMillis(long lastTimestamp) { long timestamp = System.currentTimeMillis(); while (timestamp <= lastTimestamp) { timestamp = System.currentTimeMillis(); } return timestamp; } } ``` 使用时,可以通过以下方式调用: ``` SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(workerId, datacenterId); long id = idGenerator.generateId(); ``` 以上就是用Java语言实现雪花算法生成ID的示例。 ### 回答3: 雪花算法是一种用于分布式系统中生成唯一ID的算法。它的原理是将时间戳、机器ID和序列号结合起来生成一个64位的唯一ID。 在Java中实现雪花算法可以按照以下步骤进行: 1. 定义相关常量 定义一个起始时间戳,用于计算生成ID的时间差值; 定义机器ID,可以使用IP地址或其他方式获取; 定义序列号,用于保证每个时间戳内生成的ID的唯一性。 2. 创建一个雪花算法生成ID的类 可以使用Java的类来实现,命名为SnowflakeIdGenerator。 3. 初始化相关参数 在类中定义私有变量,分别表示上一次生成ID的时间戳、机器ID和序列号。 4. 实现算法逻辑 a. 获取当前时间戳,并减去起始时间戳,得到时间差值,保证生成的ID是递增的; b. 判断当前时间戳是否和上一次生成ID的时间戳相等,若相等,则需要等待下一毫秒再生成ID; c. 设置序列号为0,表示新的时间戳内的第一个ID; d. 更新上一次生成ID的时间戳为当前时间戳; e. 将时间戳左移22位,将机器ID左移12位,然后将它们按位或操作,将这个结果和序列号按位或操作,得到最终的ID值。 5. 提供对外方法 可以提供一个公共方法nextId(),用于生成一个ID。 6. 测试与使用 在其他程序中调用SnowflakeIdGenerator的nextId()方法即可生成唯一ID。 这样,我们就可以用Java实现一个基于雪花算法的生成ID的类。同时,需要注意保证机器ID的唯一性,避免在分布式环境中生成相同的ID。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值