You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unix时间戳自定义加解密结果不一致问题(新加坡UTC时区)

自定义Unix时间戳加解密函数不一致问题排查与修复

问题背景

现有针对Unix时间戳的自定义加解密函数,输入参考码为const referenceCode = "1680698995321";(基于新加坡UTC+8时区),测试发现加密后解密结果与原参考码不一致:

  • 加密结果:040523-8995321
  • 解密结果:1680688995321
  • 对比:1680698995321 !== 1680688995321

原加密函数

const encryptCode = (referenceNo: string) => {
        const refCode = referenceNo.slice(6);
        const refModified = referenceNo.slice(0, 6) + "0".repeat(7);
        const refInt = parseInt(refModified);
        const date = new Date(refInt);
        const formattedDate = date.toLocaleDateString("fil-PH", { month: "2-digit", day: "2-digit", year: "2-digit" }).replace(/\//g, '');
        return `${formattedDate}-${refCode}`;
    }

原解密函数

const decryptCode = (encryptedCode: string) => {
        const dateRef = encryptedCode.slice(0, 6);
        const dateCode = encryptedCode.slice(7);
        const dateMonth = dateRef.slice(0, 2);
        const dateDay = dateRef.slice(2, 4);
        const dateYear = dateRef.slice(4);
        const dateString = `${dateMonth}/${dateDay}/${dateYear} 8:00:00 UTC`;
        const date = new Date(dateString);
        const timestamp  = date.getTime();
        const result = timestamp.toString().slice(0, 6) + "0".repeat(7)
        return parseInt(result) + parseInt(dateCode);
    }

问题原因

核心问题是时区处理逻辑不一致:

  1. 加密阶段:refModified是原时间戳前6位拼接7个0(即1680690000000),对应UTC时间2023-04-05T00:00:00Z,在菲律宾/新加坡时区(UTC+8)下本地时间为2023-04-05 08:00:00,通过toLocaleDateString("fil-PH")得到日期040523。
  2. 解密阶段:错误构造了UTC时间2023-04-05T08:00:00Z(对应本地时间2023-04-05 16:00:00),生成的时间戳前6位为168072,与加密时的168069不符,最终导致结果偏差10^7毫秒。

修复方案

修改解密函数,确保时区逻辑与加密阶段一致,还原出正确的refModified时间戳。以下提供两种可靠方案:

方案一:基于UTC时间构造匹配的时间点

直接构造UTC时区的当日0点,对应本地时区(UTC+8)的8点,与加密阶段的时间点完全匹配:

const decryptCode = (encryptedCode: string) => {
    const dateRef = encryptedCode.slice(0, 6);
    const dateCode = encryptedCode.slice(7);
    const dateMonth = dateRef.slice(0, 2);
    const dateDay = dateRef.slice(2, 4);
    const dateYear = dateRef.slice(4);
    // 构造UTC时间的当月当日0点,对应本地时区8点
    const dateString = `${dateMonth}/${dateDay}/${dateYear} 00:00:00 UTC`;
    const date = new Date(dateString);
    const timestamp = date.getTime();
    const result = timestamp.toString().slice(0, 6) + "0".repeat(7);
    return parseInt(result) + parseInt(dateCode);
}

方案二:直接构造本地时区时间(更可靠)

通过Date构造函数直接创建本地时区的当日8点,避免字符串解析的时区歧义:

const decryptCode = (encryptedCode: string) => {
    const dateRef = encryptedCode.slice(0, 6);
    const dateCode = encryptedCode.slice(7);
    const dateMonth = parseInt(dateRef.slice(0, 2)) - 1; // 月份从0开始
    const dateDay = parseInt(dateRef.slice(2, 4));
    const dateYear = 2000 + parseInt(dateRef.slice(4));
    // 构造本地时区(UTC+8)的当月当日8点
    const date = new Date(dateYear, dateMonth, dateDay, 8, 0, 0);
    const timestamp = date.getTime();
    const result = timestamp.toString().slice(0, 6) + "0".repeat(7);
    return parseInt(result) + parseInt(dateCode);
}

验证结果

修复后重新测试:

console.log(encryptCode(referenceCode)); // 040523-8995321
console.log(decryptCode(encryptCode(referenceCode))); // 1680698995321
referenceCode === decryptCode(encryptCode(referenceCode)) // true

内容的提问来源于stack exchange,提问作者John Joseph

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 18:32:29