KLALB V3.4

This commit is contained in:
Administrator
2025-11-15 11:08:16 +08:00
parent 306bfd36f7
commit 8842566ee2
160 changed files with 18540 additions and 4512 deletions
+367
View File
@@ -0,0 +1,367 @@
package org.kne.cloud.clock;
import java.math.BigInteger;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import org.kne.math.Long128;
public class NTPTimestamps {
// 常量定义
public static final BigInteger NANOS_PER_SECOND = BigInteger.valueOf(1_000_000_000L);
public static final BigInteger NANOS_PER_MILLIS = BigInteger.valueOf(1_000_000L);
// NTP 纪元 (1900) 和 Unix 纪元 (1970) 之间的纳秒差
public static final BigInteger NTP_EPOCH_OFFSET_NS = BigInteger.valueOf(2208988800L)
.multiply(NANOS_PER_SECOND);
// 2^64 值,用于单位转换
public static final BigInteger TWO_POW_64 = BigInteger.ONE.shiftLeft(64);
// 2^32 值,用于 64 位时间戳处理
public static final BigInteger TWO_POW_32 = BigInteger.ONE.shiftLeft(32);
// 掩码常量
public static final BigInteger MASK_32_BIT = new BigInteger("FFFFFFFF", 16);
public static final BigInteger MASK_64_BIT = new BigInteger("FFFFFFFFFFFFFFFF", 16);
// ================== 核心转换方法 ==================
// 2^32 秒,约 136.192 年,一个 NTP 纪元的长度
public static final BigInteger SECONDS_PER_ERA = BigInteger.valueOf(0x100000000L);
public static BigInteger inferNtp64To128(long remote64Bit,BigInteger local128Bit ) {
return inferNtp64To128(toUnsignedBigInteger(remote64Bit),local128Bit);
}
/**
* 根据本地 128 位时间戳和网络 64 位时间戳,推断并补全纪元信息
*
* @param remote64Bit 从网络接收的 64 位 NTP 时间戳
* @param local128Bit 本地已知的 128 位 NTP 时间戳
* @return 推断出的完整 128 位 NTP 时间戳
*/
public static BigInteger inferNtp64To128(BigInteger remote64Bit,BigInteger local128Bit ) {
// 1. 从本地 128 位时间戳中提取纪元号和 64 位时间戳部分
BigInteger localEra = NTPTimestamps.getEraNumber(local128Bit);
BigInteger local64Bit = NTPTimestamps.getNtp64Timestamp(local128Bit);
// 3. 计算本地和远程 64 位时间戳的差异
BigInteger difference = remote64Bit.subtract(local64Bit);
// 4. 判断纪元关系并推断远程时间戳的纪元
BigInteger remoteEra;
// 如果差异很大(超过半个纪元),可能需要调整纪元
BigInteger halfEra = BigInteger.valueOf(Long.MAX_VALUE);
if (difference.compareTo(halfEra) > 0) {
// 远程时间戳比本地小很多,可能属于上一个纪元
remoteEra = localEra.subtract(BigInteger.ONE);
} else if (difference.compareTo(halfEra.negate()) < 0) {
// 远程时间戳比本地大很多,可能属于下一个纪元
remoteEra = localEra.add(BigInteger.ONE);
} else {
// 差异不大,属于同一个纪元
remoteEra = localEra;
}
// 5. 组合纪元号和 64 位时间戳,得到完整的 128 位时间戳
return NTPTimestamps.ntp64To128(remote64Bit, remoteEra);
}
/**
* 将从1970年开始的纳秒数转换为 NTPv4 128 位时间戳
* 128位时间戳表示从1900年1月1日起经过的 2⁻⁶⁴ 秒的数量
*/
public static BigInteger nanosToNtp128BitTimestamp(Long128 nanosSince1970) {
// 1. 计算从 1900 年开始的总纳秒数
BigInteger totalNanosFrom1900 = nanosSince1970.toBigInteger().add(NTP_EPOCH_OFFSET_NS);
// 2. 将纳秒转换为 2⁻⁶⁴ 秒单位
return totalNanosFrom1900.multiply(TWO_POW_64).divide(NANOS_PER_SECOND);
}
/**
* 从 NTPv4 128 位时间戳转换回从1970年开始的纳秒数
*/
public static Long128 ntp128BitToNanosTimestamp(BigInteger ntp128Timestamp) {
// 1. 将 2⁻⁶⁴ 秒单位转换回纳秒
BigInteger totalNanosFrom1900 = ntp128Timestamp.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
// 2. 计算从 1970 年开始的总纳秒数
return Long128.valueOf( totalNanosFrom1900.subtract(NTP_EPOCH_OFFSET_NS));
}
public static BigInteger nanosToNtp128BitTimeInterval(BigInteger nanos) {
// 2. 将纳秒转换为 2⁻⁶⁴ 秒单位
return nanos.multiply(TWO_POW_64).divide(NANOS_PER_SECOND);
}
public static BigInteger ntp128BitToNanosInterval(BigInteger ntp128Timestamp) {
// 1. 将 2⁻⁶⁴ 秒单位转换回纳秒
BigInteger totalNanosFrom1900 = ntp128Timestamp.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
return totalNanosFrom1900;
}
// ================== 128位 ↔ 64位 转换 ==================
/**
* 将 NTP 128 位时间戳转换为 NTP 64 位时间戳
* 64位时间戳就是128位时间戳的中间64位
*/
public static BigInteger ntp128To64(BigInteger ntp128Timestamp) {
return ntp128Timestamp.shiftRight(32).and(MASK_64_BIT);
}
/**
* 将 NTP 64 位时间戳转换为 NTP 128 位时间戳
* 64位时间戳放在128位时间戳的中间64位,高32位Era和低32位分数为0
*/
public static BigInteger ntp64To128(BigInteger ntp64Timestamp) {
return ntp64Timestamp.and(MASK_64_BIT).shiftLeft(32);
}
/**
* 将 NTP 64 位时间戳转换为 NTP 128 位时间戳(指定Era Number
*/
public static BigInteger ntp64To128(BigInteger ntp64Timestamp, BigInteger eraNumber) {
return eraNumber.and(MASK_32_BIT).shiftLeft(96)
.or(ntp64Timestamp.and(MASK_64_BIT).shiftLeft(32));
}
/**
* 从 NTP 128 位时间戳中提取 Era Number(高32位)
*/
public static BigInteger getEraNumber(BigInteger ntp128Timestamp) {
return ntp128Timestamp.shiftRight(96).and(MASK_32_BIT);
}
/**
* 从 NTP 128 位时间戳中提取 64 位时间戳(中间64位)
*/
public static BigInteger getNtp64Timestamp(BigInteger ntp128Timestamp) {
return ntp128Timestamp.shiftRight(32).and(MASK_64_BIT);
}
/**
* 从 NTP 128 位时间戳中提取分数部分(低32位)
*/
public static BigInteger getFraction(BigInteger ntp128Timestamp) {
return ntp128Timestamp.and(MASK_32_BIT);
}
// ================== 工具方法 ==================
/**
* 从毫秒和纳秒偏移构造 BigInteger 纳秒
*/
public static Long128 toNanosSince1970(long unixTimeMillis, long nanosOffset) {
return Long128.valueOf(unixTimeMillis)
.multiply(Long128.valueOf( NANOS_PER_MILLIS))
.add(Long128.valueOf(nanosOffset));
}
/**
* 从 BigInteger 纳秒提取毫秒和纳秒偏移
*/
public static long[] toMillisAndNanos(Long128 nanosSince1970) {
Long128[] millisAndNanos = nanosSince1970.divideAndRemainder(Long128.valueOf( NANOS_PER_MILLIS));
return new long[]{millisAndNanos[0].longValue(), millisAndNanos[1].longValue()};
}
/**
* 计算两个 128 位时间戳之间的时间差(纳秒)
*/
public static BigInteger calculateTimeDifference(BigInteger timestamp1, BigInteger timestamp2) {
BigInteger diff = timestamp2.subtract(timestamp1);
return diff.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
}
/**
* 将 64 位 NTP 时间戳分解为秒数和分数
*/
public static BigInteger[] parseNtp64Timestamp(BigInteger ntp64Timestamp) {
BigInteger seconds = ntp64Timestamp.shiftRight(32).and(MASK_32_BIT);
BigInteger fraction = ntp64Timestamp.and(MASK_32_BIT);
return new BigInteger[]{seconds, fraction};
}
/**
* 从秒数和分数构建 64 位 NTP 时间戳
*/
public static BigInteger buildNtp64Timestamp(BigInteger seconds, BigInteger fraction) {
return seconds.and(MASK_32_BIT).shiftLeft(32).or(fraction.and(MASK_32_BIT));
}
// ================== 测试代码 ==================
public static void main(String[] args) {
System.out.println("=== NTPv4 128位/64位时间戳转换测试 ===");
// 测试当前时间
testCurrentTime();
// 测试 128位 ↔ 64位 转换
test128To64Conversion();
// 测试 Era Number 处理
testEraNumberHandling();
// 测试边界值
testBoundaryValues();
}
private static void testCurrentTime() {
System.out.println("\n=== 当前时间测试 ===");
Long128 nanosSince1970 = toNanosSince1970(System.currentTimeMillis(), 123456);
BigInteger ntp128 = nanosToNtp128BitTimestamp(nanosSince1970);
BigInteger ntp64 = ntp128To64(ntp128);
System.out.println("从1970年开始的纳秒数: " + nanosSince1970);
System.out.println("NTP 128-bit: 0x" + ntp128.toString(16).toUpperCase());
System.out.println("NTP 64-bit: 0x" + ntp64.toString(16).toUpperCase());
// 反向转换验证
BigInteger recovered128 = ntp64To128(ntp64);
Long128 recoveredNanos = ntp128BitToNanosTimestamp(recovered128);
System.out.println("恢复的纳秒数: " + recoveredNanos);
System.out.println("转换正确: " + (nanosSince1970.equals(recoveredNanos) ? "" : ""));
}
private static void test128To64Conversion() {
System.out.println("\n=== 128位 ↔ 64位 转换测试 ===");
// 创建一个测试用的 128 位时间戳
BigInteger test128 = new BigInteger("EC652B7E912F00B81234567890ABCDEF", 16);
BigInteger ntp64 = ntp128To64(test128);
BigInteger recovered128 = ntp64To128(ntp64);
System.out.println("原始128位: 0x" + test128.toString(16).toUpperCase());
System.out.println("转换64位: 0x" + ntp64.toString(16).toUpperCase());
System.out.println("恢复128位: 0x" + recovered128.toString(16).toUpperCase());
// 验证中间64位相同
BigInteger original64Part = getNtp64Timestamp(test128);
System.out.println("转换正确: " + (original64Part.equals(ntp64) ? "" : ""));
}
private static void testEraNumberHandling() {
System.out.println("\n=== Era Number 处理测试 ===");
BigInteger ntp64 = new BigInteger("EC652B7E912F00B8", 16);
BigInteger eraNumber = new BigInteger("1", 16); // Era 1
BigInteger ntp128WithEra = ntp64To128(ntp64, eraNumber);
BigInteger extractedEra = getEraNumber(ntp128WithEra);
BigInteger extracted64 = getNtp64Timestamp(ntp128WithEra);
System.out.println("设置 Era: 0x" + eraNumber.toString(16).toUpperCase());
System.out.println("提取 Era: 0x" + extractedEra.toString(16).toUpperCase());
System.out.println("提取 64位: 0x" + extracted64.toString(16).toUpperCase());
System.out.println("128位值: 0x" + ntp128WithEra.toString(16).toUpperCase());
System.out.println("Era 正确: " + (eraNumber.equals(extractedEra) ? "" : ""));
System.out.println("64位正确: " + (ntp64.equals(extracted64) ? "" : ""));
}
private static void testBoundaryValues() {
System.out.println("\n=== 边界值测试 ===");
// 测试最大值
BigInteger max64 = MASK_64_BIT; // 0xFFFFFFFFFFFFFFFF
BigInteger max128 = ntp64To128(max64);
BigInteger recovered64 = ntp128To64(max128);
System.out.println("最大64位: 0x" + max64.toString(16).toUpperCase());
System.out.println("转换128位: 0x" + max128.toString(16).toUpperCase());
System.out.println("恢复64位: 0x" + recovered64.toString(16).toUpperCase());
System.out.println("最大值转换正确: " + (max64.equals(recovered64) ? "" : ""));
// 测试 Era Number 边界
BigInteger maxEra = MASK_32_BIT; // 0xFFFFFFFF
BigInteger test64 = new BigInteger("1234567890ABCDEF", 16);
BigInteger ntp128MaxEra = ntp64To128(test64, maxEra);
BigInteger extractedMaxEra = getEraNumber(ntp128MaxEra);
System.out.println("最大Era转换正确: " + (maxEra.equals(extractedMaxEra) ? "" : ""));
}
/**
* 生成时间序列测试
*/
public static void testTimeSeries() {
System.out.println("\n=== 时间序列测试 ===");
Long128 startNanos = toNanosSince1970(System.currentTimeMillis(), 0);
BigInteger start128 = nanosToNtp128BitTimestamp(startNanos);
for (int i = 0; i < 5; i++) {
Long128 offsetNanos = Long128.valueOf(i).multiply(Long128.valueOf( NANOS_PER_SECOND).divide(Long128.valueOf(10)));
Long128 currentNanos = startNanos.add(offsetNanos);
BigInteger current128 = nanosToNtp128BitTimestamp(currentNanos);
BigInteger current64 = ntp128To64(current128);
long[] time = toMillisAndNanos(currentNanos);
System.out.printf("时间: %d ms + %d ns -> 64位: %s -> 128位: %s%n",
time[0], time[1],
current64.toString(16).toUpperCase(),
current128.toString(16).toUpperCase());
}
}
// 日期时间格式化器
private static final DateTimeFormatter DEFAULT_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
private static final DateTimeFormatter DETAILED_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.n");
public static String nanosSince1970ToString(Long128 nanos) {
Long128 millis = nanos.divide(Long128.valueOf(1_000_000));
Long128 nanosPart = nanos.mod(Long128.valueOf(1_000_000));
Instant instant = Instant.ofEpochMilli(millis.longValue());
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
return String.format("%s.%06d",
DEFAULT_FORMATTER.format(dateTime),
nanosPart.longValue());
}
/**
* 将 128 位时间戳转换为可读字符串
*/
public static String ntp128ToString(BigInteger ntp128Timestamp) {
Long128 nanosSince1970 = ntp128BitToNanosTimestamp(ntp128Timestamp);
return nanosSince1970ToString(nanosSince1970);
}
/**
* 将 64 位时间戳转换为可读字符串
*/
public static String ntp64ToString(BigInteger ntp64Timestamp) {
Long128 nanosSince1970 = ntp128BitToNanosTimestamp(ntp64To128( ntp64Timestamp));
return nanosSince1970ToString(nanosSince1970);
}
public static BigInteger toUnsignedBigInteger(long unsignedLong) {
if (unsignedLong >= 0) {
return BigInteger.valueOf(unsignedLong);
} else {
// 对于负数,通过添加 2^64 来转换为无符号表示
return BigInteger.valueOf(unsignedLong & 0x7FFFFFFFFFFFFFFFL)
.setBit(63);
}
}
}