KLALB V3.6.0 写了一半

This commit is contained in:
Administrator
2026-02-27 08:32:03 +08:00
parent 816e672843
commit 620afef715
164 changed files with 8381 additions and 13495 deletions
+60 -168
View File
@@ -1,6 +1,5 @@
package org.kne.cloud.clock;
import java.math.BigInteger;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
@@ -12,29 +11,30 @@ 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);
public static final Long128 NANOS_PER_SECOND = Long128.valueOf(1_000_000_000L);
public static final Long128 NANOS_PER_MILLIS = Long128.valueOf(1_000_000L);
// NTP 纪元 (1900) 和 Unix 纪元 (1970) 之间的纳秒差
public static final BigInteger NTP_EPOCH_OFFSET_NS = BigInteger.valueOf(2208988800L)
public static final Long128 NTP_EPOCH_OFFSET_NS = Long128.valueOf(2208988800L)
.multiply(NANOS_PER_SECOND);
// 2^64 值,用于单位转换
public static final BigInteger TWO_POW_64 = BigInteger.ONE.shiftLeft(64);
public static final Long128 TWO_POW_64 = Long128.ONE.shiftLeft(64);
// 2^32 值,用于 64 位时间戳处理
public static final BigInteger TWO_POW_32 = BigInteger.ONE.shiftLeft(32);
public static final Long128 TWO_POW_32 = Long128.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);
public static final Long128 MASK_32_BIT = new Long128(0xFFFFFFFF);
public static final Long128 MASK_64_BIT = new Long128(0xFFFFFFFFFFFFFFFFL);
// ================== 核心转换方法 ==================
// 2^32 秒,约 136.192 年,一个 NTP 纪元的长度
public static final BigInteger SECONDS_PER_ERA = BigInteger.valueOf(0x100000000L);
public static final Long128 SECONDS_PER_ERA = Long128.valueOf(0x100000000L);
private static final Long128 TWO_POW_N64_PER_NANOS = Long128.valueOf("1208925819614629");
public static BigInteger inferNtp64To128(long remote64Bit,BigInteger local128Bit ) {
return inferNtp64To128(toUnsignedBigInteger(remote64Bit),local128Bit);
public static Long128 inferNtp64To128(long remote64Bit,Long128 local128Bit ) {
return inferNtp64To128(toUnsignedLong128(remote64Bit),local128Bit);
}
@@ -45,26 +45,26 @@ public class NTPTimestamps {
* @param local128Bit 本地已知的 128 位 NTP 时间戳
* @return 推断出的完整 128 位 NTP 时间戳
*/
public static BigInteger inferNtp64To128(BigInteger remote64Bit,BigInteger local128Bit ) {
public static Long128 inferNtp64To128(Long128 remote64Bit,Long128 local128Bit ) {
// 1. 从本地 128 位时间戳中提取纪元号和 64 位时间戳部分
BigInteger localEra = NTPTimestamps.getEraNumber(local128Bit);
BigInteger local64Bit = NTPTimestamps.getNtp64Timestamp(local128Bit);
Long128 localEra = NTPTimestamps.getEraNumber(local128Bit);
Long128 local64Bit = NTPTimestamps.getNtp64Timestamp(local128Bit);
// 3. 计算本地和远程 64 位时间戳的差异
BigInteger difference = remote64Bit.subtract(local64Bit);
Long128 difference = remote64Bit.subtract(local64Bit);
// 4. 判断纪元关系并推断远程时间戳的纪元
BigInteger remoteEra;
Long128 remoteEra;
// 如果差异很大(超过半个纪元),可能需要调整纪元
BigInteger halfEra = BigInteger.valueOf(Long.MAX_VALUE);
Long128 halfEra = Long128.valueOf(Long.MAX_VALUE);
if (difference.compareTo(halfEra) > 0) {
// 远程时间戳比本地小很多,可能属于上一个纪元
remoteEra = localEra.subtract(BigInteger.ONE);
remoteEra = localEra.subtract(Long128.ONE);
} else if (difference.compareTo(halfEra.negate()) < 0) {
// 远程时间戳比本地大很多,可能属于下一个纪元
remoteEra = localEra.add(BigInteger.ONE);
remoteEra = localEra.add(Long128.ONE);
} else {
// 差异不大,属于同一个纪元
remoteEra = localEra;
@@ -77,35 +77,36 @@ public class NTPTimestamps {
* 将从1970年开始的纳秒数转换为 NTPv4 128 位时间戳
* 128位时间戳表示从1900年1月1日起经过的 2⁻⁶⁴ 秒的数量
*/
public static BigInteger nanosToNtp128BitTimestamp(Long128 nanosSince1970) {
public static Long128 nanosToNtp128BitTimestamp(Long128 nanosSince1970) {
// 1. 计算从 1900 年开始的总纳秒数
BigInteger totalNanosFrom1900 = nanosSince1970.toBigInteger().add(NTP_EPOCH_OFFSET_NS);
Long128 totalNanosFrom1900 = nanosSince1970.add(NTP_EPOCH_OFFSET_NS);
// 2. 将纳秒转换为 2⁻⁶⁴ 秒单位
return totalNanosFrom1900.multiply(TWO_POW_64).divide(NANOS_PER_SECOND);
// return totalNanosFrom1900.multiply(TWO_POW_64).divide(NANOS_PER_SECOND);
return totalNanosFrom1900.multiply(TWO_POW_N64_PER_NANOS).shiftRight(16);
}
/**
* 从 NTPv4 128 位时间戳转换回从1970年开始的纳秒数
*/
public static Long128 ntp128BitToNanosTimestamp(BigInteger ntp128Timestamp) {
public static Long128 ntp128BitToNanosTimestamp(Long128 ntp128Timestamp) {
// 1. 将 2⁻⁶⁴ 秒单位转换回纳秒
BigInteger totalNanosFrom1900 = ntp128Timestamp.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
Long128 totalNanosFrom1900 = ntp128Timestamp.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
// 2. 计算从 1970 年开始的总纳秒数
return Long128.valueOf( totalNanosFrom1900.subtract(NTP_EPOCH_OFFSET_NS));
return totalNanosFrom1900.subtract(NTP_EPOCH_OFFSET_NS);
}
public static BigInteger nanosToNtp128BitTimeInterval(BigInteger nanos) {
public static Long128 nanosToNtp128BitTimeInterval(Long128 nanos) {
// 2. 将纳秒转换为 2⁻⁶⁴ 秒单位
return nanos.multiply(TWO_POW_64).divide(NANOS_PER_SECOND);
}
public static BigInteger ntp128BitToNanosInterval(BigInteger ntp128Timestamp) {
public static Long128 ntp128BitToNanosInterval(Long128 ntp128Timestamp) {
// 1. 将 2⁻⁶⁴ 秒单位转换回纳秒
BigInteger totalNanosFrom1900 = ntp128Timestamp.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
Long128 totalNanosFrom1900 = ntp128Timestamp.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
return totalNanosFrom1900;
}
@@ -117,7 +118,7 @@ public class NTPTimestamps {
* 将 NTP 128 位时间戳转换为 NTP 64 位时间戳
* 64位时间戳就是128位时间戳的中间64位
*/
public static BigInteger ntp128To64(BigInteger ntp128Timestamp) {
public static Long128 ntp128To64(Long128 ntp128Timestamp) {
return ntp128Timestamp.shiftRight(32).and(MASK_64_BIT);
}
@@ -125,14 +126,14 @@ public class NTPTimestamps {
* 将 NTP 64 位时间戳转换为 NTP 128 位时间戳
* 64位时间戳放在128位时间戳的中间64位,高32位Era和低32位分数为0
*/
public static BigInteger ntp64To128(BigInteger ntp64Timestamp) {
public static Long128 ntp64To128(Long128 ntp64Timestamp) {
return ntp64Timestamp.and(MASK_64_BIT).shiftLeft(32);
}
/**
* 将 NTP 64 位时间戳转换为 NTP 128 位时间戳(指定Era Number
*/
public static BigInteger ntp64To128(BigInteger ntp64Timestamp, BigInteger eraNumber) {
public static Long128 ntp64To128(Long128 ntp64Timestamp, Long128 eraNumber) {
return eraNumber.and(MASK_32_BIT).shiftLeft(96)
.or(ntp64Timestamp.and(MASK_64_BIT).shiftLeft(32));
}
@@ -140,48 +141,48 @@ public class NTPTimestamps {
/**
* 从 NTP 128 位时间戳中提取 Era Number(高32位)
*/
public static BigInteger getEraNumber(BigInteger ntp128Timestamp) {
public static Long128 getEraNumber(Long128 ntp128Timestamp) {
return ntp128Timestamp.shiftRight(96).and(MASK_32_BIT);
}
/**
* 从 NTP 128 位时间戳中提取 64 位时间戳(中间64位)
*/
public static BigInteger getNtp64Timestamp(BigInteger ntp128Timestamp) {
public static Long128 getNtp64Timestamp(Long128 ntp128Timestamp) {
return ntp128Timestamp.shiftRight(32).and(MASK_64_BIT);
}
/**
* 从 NTP 128 位时间戳中提取分数部分(低32位)
*/
public static BigInteger getFraction(BigInteger ntp128Timestamp) {
public static Long128 getFraction(Long128 ntp128Timestamp) {
return ntp128Timestamp.and(MASK_32_BIT);
}
// ================== 工具方法 ==================
/**
* 从毫秒和纳秒偏移构造 BigInteger 纳秒
* 从毫秒和纳秒偏移构造 Long128 纳秒
*/
public static Long128 toNanosSince1970(long unixTimeMillis, long nanosOffset) {
return Long128.valueOf(unixTimeMillis)
.multiply(Long128.valueOf( NANOS_PER_MILLIS))
.multiply( NANOS_PER_MILLIS)
.add(Long128.valueOf(nanosOffset));
}
/**
* 从 BigInteger 纳秒提取毫秒和纳秒偏移
* 从 Long128 纳秒提取毫秒和纳秒偏移
*/
public static long[] toMillisAndNanos(Long128 nanosSince1970) {
Long128[] millisAndNanos = nanosSince1970.divideAndRemainder(Long128.valueOf( NANOS_PER_MILLIS));
Long128[] millisAndNanos = nanosSince1970.divideAndRemainder( 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);
public static Long128 calculateTimeDifference(Long128 timestamp1, Long128 timestamp2) {
Long128 diff = timestamp2.subtract(timestamp1);
return diff.multiply(NANOS_PER_SECOND).divide(TWO_POW_64);
}
@@ -190,137 +191,20 @@ public class NTPTimestamps {
/**
* 将 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};
public static Long128[] parseNtp64Timestamp(Long128 ntp64Timestamp) {
Long128 seconds = ntp64Timestamp.shiftRight(32).and(MASK_32_BIT);
Long128 fraction = ntp64Timestamp.and(MASK_32_BIT);
return new Long128[]{seconds, fraction};
}
/**
* 从秒数和分数构建 64 位 NTP 时间戳
*/
public static BigInteger buildNtp64Timestamp(BigInteger seconds, BigInteger fraction) {
public static Long128 buildNtp64Timestamp(Long128 seconds, Long128 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 =
@@ -338,11 +222,19 @@ public class NTPTimestamps {
DEFAULT_FORMATTER.format(dateTime),
nanosPart.longValue());
}
public static String nanosSince1970ToString2(Long128 nanos) {
Long128 millis = nanos.divide(Long128.valueOf(1_000_000));
Instant instant = Instant.ofEpochMilli(millis.longValue());
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
return DEFAULT_FORMATTER.format(dateTime);
}
/**
* 将 128 位时间戳转换为可读字符串
*/
public static String ntp128ToString(BigInteger ntp128Timestamp) {
public static String ntp128ToString(Long128 ntp128Timestamp) {
Long128 nanosSince1970 = ntp128BitToNanosTimestamp(ntp128Timestamp);
return nanosSince1970ToString(nanosSince1970);
}
@@ -350,17 +242,17 @@ public class NTPTimestamps {
/**
* 将 64 位时间戳转换为可读字符串
*/
public static String ntp64ToString(BigInteger ntp64Timestamp) {
public static String ntp64ToString(Long128 ntp64Timestamp) {
Long128 nanosSince1970 = ntp128BitToNanosTimestamp(ntp64To128( ntp64Timestamp));
return nanosSince1970ToString(nanosSince1970);
}
public static BigInteger toUnsignedBigInteger(long unsignedLong) {
public static Long128 toUnsignedLong128(long unsignedLong) {
if (unsignedLong >= 0) {
return BigInteger.valueOf(unsignedLong);
return Long128.valueOf(unsignedLong);
} else {
// 对于负数,通过添加 2^64 来转换为无符号表示
return BigInteger.valueOf(unsignedLong & 0x7FFFFFFFFFFFFFFFL)
return Long128.valueOf(unsignedLong & 0x7FFFFFFFFFFFFFFFL)
.setBit(63);
}
}