我正在通过数据捕获产品从大型机发送一些交易数据(以json格式)。在JSON中,它们应该发送一个值,该值是大型机timeOfDay(TOD)值,表示等效的事务时间戳。 而不是发送值“stck”:“00d2fde04305b72642”
他们反而向我发送“stck”:“\ u00c3 \ u00c \ u00c \ u00c \ u00c \ u00c \ u00c \ u00c \ u00c \ u00c \ u00c \ u00c \ u00c \ u00c 当我问他们为什么说“
时“上面的内容(”stck“:”00d2fde04305b72642“)是二进制数据UTF-16格式.JSON不能很好地处理二进制数据,所以我们将其转换为十六进制UTF-8格式。你可以转换它回到你身边的UTF-16“
我需要在java中帮助这样做。我已经看到了多个问题,但没有什么能完全符合我的要求,将十六进制UTF-8转换为UTF-16,希望看起来像“00d2fde04305b72642”
我已经能够找到一个问题,显示如何使用java将这个产生的TOD值(“stck”:“00d2fde04305b72642”)转换为事务时间戳,所以我在那部分内容已经涵盖了。
答案 0 :(得分:1)
"他们"做错了。他们应该简单地对base-16中的数值进行编码并使用结果字符串。
他们正在做的是将数值的字节视为字符,并使用UTF-8对它们进行编码。然后,他们获取这些字节并在非ASCII字符上应用Unicode转义序列。当被问及这个过程时,当他们对伤害进行侮辱时,他们的回答是胡说八道。它在很多层面都是一场灾难。
以下内容应该允许您恢复数据并转换为Java时间戳。
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
public class SO45704851
{
public static void main(String... argv)
throws Exception
{
String example = "\u00c3\u0092\u00c3\u00bd\u00c2\u00aa\u00c2\u009e\u001c\u00c2\u0089\u001cG";
long tod = sbrogliare(example);
System.out.printf("ToD: 0x%016x%n", tod);
Instant time = toInstant(tod);
System.out.printf("Instant: %s%n", time);
}
/**
* Clean up an infernal mess, miraculously bestowing a 64-bit time-of-day.
*/
public static long sbrogliare(String garbage)
{
byte[] utf8 = new byte[garbage.length()];
for (int idx = 0; idx < garbage.length(); ++idx)
utf8[idx] = (byte) garbage.charAt(idx);
String raw = new String(utf8, StandardCharsets.UTF_8);
if (raw.length() != 8)
throw new IllegalArgumentException();
long n = 0;
for (int idx = 0; idx < raw.length(); ++idx) {
char ch = raw.charAt(idx);
if (ch > 255)
throw new IllegalArgumentException();
n = n << 8 | ch;
}
return n;
}
private static final OffsetDateTime zero = OffsetDateTime.parse("1900-01-01T00:00Z");
/**
* Convert 64-bit time-of-day to {@code Instant}.
*/
public static Instant toInstant(long tod)
{
long nanos = (125 * (tod >>> 32) << 23) + (125 * (tod & 0xFFFFFFFFL) >>> 9);
return zero.plus(nanos, ChronoUnit.NANOS).toInstant();
}
}