代码 PHP 唯一卡号生成

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

唯一卡号生成

功能概述

该 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 算法 卡号生成 软件开发

推荐文章

Vue3中如何处理状态管理?
2024-11-17 07:13:45 +0800 CST
CSS 奇技淫巧
2024-11-19 08:34:21 +0800 CST
Vue3中的组件通信方式有哪些?
2024-11-17 04:17:57 +0800 CST
PHP 压缩包脚本功能说明
2024-11-19 03:35:29 +0800 CST
Web 端 Office 文件预览工具库
2024-11-18 22:19:16 +0800 CST
用 Rust 玩转 Google Sheets API
2024-11-19 02:36:20 +0800 CST
2024年微信小程序开发价格概览
2024-11-19 06:40:52 +0800 CST
php客服服务管理系统
2024-11-19 06:48:35 +0800 CST
Go 单元测试
2024-11-18 19:21:56 +0800 CST
html5在客户端存储数据
2024-11-17 05:02:17 +0800 CST
一个简单的打字机效果的实现
2024-11-19 04:47:27 +0800 CST
如何在Vue 3中使用Ref访问DOM元素
2024-11-17 04:22:38 +0800 CST
php内置函数除法取整和取余数
2024-11-19 10:11:51 +0800 CST
`Blob` 与 `File` 的关系
2025-05-11 23:45:58 +0800 CST
前端开发中常用的设计模式
2024-11-19 07:38:07 +0800 CST
PHP 微信红包算法
2024-11-17 22:45:34 +0800 CST
淘宝npm镜像使用方法
2024-11-18 23:50:48 +0800 CST
程序员茄子在线接单