代码 PHP 唯一卡号生成

2024-11-18 21:24:12 +0800 CST views 879

唯一卡号生成

功能概述

该 PHP 类 TkCardFlake 用于生成预付卡卡号。它通过时间戳、序号、工作节点 ID 和 Luhn 校验算法来生成唯一且符合卡号格式的字符串。

主要功能模块

  1. 类常量

    • INIT_DATE: 初始时间戳,用于计算相对时间。
    • SEQUENCE_MAX: 序列号的最大值,限制在 999 以内。
  2. 构造函数

    • 初始化类的实例,设置 workerIdworkerId 不能超过 9,否则抛出异常。
  3. GetCardInfo 方法

    • 生成卡号的核心方法,通过当前时间戳和序列号生成卡号,并附加 Luhn 校验码。
  4. now 方法

    • 返回当前的 Unix 时间戳(秒)。
  5. luhnCheck 方法

    • 实现 Luhn 算法,用于生成卡号的校验码。

代码优化与说明

<?php

namespace Extend;

use Exception;

// 生成预付卡卡号
class TkCardFlake
{
    // 初始化常量
    public const INIT_DATE    = 1691352000; // '2023-08-07 04:00:00 000';
    public const SEQUENCE_MAX = 999; // 序号最大值

    public int $workerId  = 0;
    public int $sequence  = 0;
    public int $timestamp = 0;

    /**
     * 构造函数,初始化 workerId
     * @param int $workerId
     * @throws Exception
     */
    public function __construct(int $workerId = 0)
    {
        if ($workerId > 9) {
            throw new Exception('生成卡号失败,workerId不能大于9。');
        }
        $this->workerId = $workerId;
    }

    /**
     * 生成卡号
     * @param string $cardBin 卡片前缀
     * @return string
     * @throws Exception
     */
    public function GetCardInfo(string $cardBin): string
    {
        $now = $this->now();

        if ($this->timestamp == $now) {
            $this->sequence++;
            if ($this->sequence > self::SEQUENCE_MAX) {
                // 当前毫秒内生成的序号已经超出最大范围,等待下一毫秒
                do {
                    $now = $this->now();
                } while ($now <= $this->timestamp);
            }
        } else {
            $this->timestamp = $now;
            $this->sequence  = 0;
        }

        $difftime = str_pad($this->timestamp - self::INIT_DATE, 10, '0', STR_PAD_LEFT);
        $sequence = str_pad($this->sequence, 3, '0', STR_PAD_LEFT);

        // 拼接卡号: workerId(1位) + difftime(10位) + sequence(3位)
        $no = $this->workerId . $difftime . $sequence;
        $cardBinNo = $cardBin . $no;

        // 计算Luhn校验码
        $checkNo = $this->luhnCheck($cardBinNo) % 10 == 0 ? 0 : 10 - ($this->luhnCheck($cardBinNo) % 10);

        return $cardBinNo . $checkNo;
    }

    /**
     * 获取当前秒级时间戳
     * @return string
     */
    private function now(): string
    {
        return time();
    }

    /**
     * 计算Luhn校验和
     * @param string $number
     * @return int
     */
    private function luhnCheck(string $number): int
    {
        $reversedNumber = strrev($number);
        $sum = 0;

        for ($i = 0; $i < strlen($reversedNumber); $i++) {
            $digit = (int)$reversedNumber[$i];
            if ($i % 2 == 1) {
                $digit *= 2;
                if ($digit > 9) {
                    $digit -= 9;
                }
            }
            $sum += $digit;
        }

        return $sum;
    }
}

代码功能说明

  1. 类属性与常量

    • INIT_DATE: 起始时间,用于计算相对时间。
    • SEQUENCE_MAX: 每秒最多生成 1000 个卡号。
  2. GetCardInfo 方法

    • 根据当前时间戳、序列号和 workerId 生成卡号。
    • 使用 Luhn 算法生成校验位。
  3. luhnCheck 方法

    • 反转卡号并对奇数位数字加倍,计算总和来生成校验位。

使用方法

  1. 创建一个 TkCardFlake 实例并传入 workerId
  2. 调用 GetCardInfo 方法并传入卡片前缀(cardBin)来生成卡号。

优化建议

  • 将时间戳和序列号处理封装成独立方法,提高代码复用性。
  • 确保 workerId 在多实例中唯一,以避免生成重复卡号。

总结

这段代码提供了一个生成唯一预付卡号的高效机制,通过时间戳、序列号和 Luhn 校验的组合确保了卡号的唯一性和有效性。

复制全文 生成海报 编程 PHP 算法 卡号生成 软件开发

推荐文章

# 解决 MySQL 经常断开重连的问题
2024-11-19 04:50:20 +0800 CST
Manticore Search:高性能的搜索引擎
2024-11-19 03:43:32 +0800 CST
Nginx 实操指南:从入门到精通
2024-11-19 04:16:19 +0800 CST
MySQL数据库的36条军规
2024-11-18 16:46:25 +0800 CST
四舍五入五成双
2024-11-17 05:01:29 +0800 CST
Nginx 反向代理 Redis 服务
2024-11-19 09:41:21 +0800 CST
如何优化网页的 SEO 架构
2024-11-18 14:32:08 +0800 CST
Golang在整洁架构中优雅使用事务
2024-11-18 19:26:04 +0800 CST
PHP解决XSS攻击
2024-11-19 02:17:37 +0800 CST
一个有趣的进度条
2024-11-19 09:56:04 +0800 CST
MySQL 日志详解
2024-11-19 02:17:30 +0800 CST
使用 Git 制作升级包
2024-11-19 02:19:48 +0800 CST
Python中何时应该使用异常处理
2024-11-19 01:16:28 +0800 CST
宝塔面板 Nginx 服务管理命令
2024-11-18 17:26:26 +0800 CST
pin.gl是基于WebRTC的屏幕共享工具
2024-11-19 06:38:05 +0800 CST
Vue3 结合 Driver.js 实现新手指引
2024-11-18 19:30:14 +0800 CST
Python 基于 SSE 实现流式模式
2025-02-16 17:21:01 +0800 CST
markdowns滚动事件
2024-11-19 10:07:32 +0800 CST
55个常用的JavaScript代码段
2024-11-18 22:38:45 +0800 CST
PHP openssl 生成公私钥匙
2024-11-17 05:00:37 +0800 CST
程序员茄子在线接单