【问题标题】:Java and .NET/PowerShell producing different UTF-8 bytesJava 和 .NET/PowerShell 产生不同的 UTF-8 字节
【发布时间】:2022-01-05 11:32:18
【问题描述】:

为此我头发变白了。 我需要将 PowerShell 中的字符串转换为 UTF-8。我的参考代码是用 Java 编写的(并且可以与更大的应用程序一起使用),所以我需要重现它的作用。

在 Java 中,我这样做:

    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();

    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
        }
        return new String(hexChars);
    }
    
    public static void main(String[] args) throws Exception {
        System.out.println(bytesToHex("aöß".getBytes("UTF8")));
    }

输出61C3B6C39F

在 PowerShell 中,我会这样做

Write-Output $(([System.Text.UTF8Encoding]::New($false, $true).getBytes("aöß") | ForEach-Object ToString X2) -join '')

输出61C383C2B6C383C5B8

为什么它们不同?如何使 PowerShell 编码与 Java 匹配?

如果有任何见解,我将不胜感激!

最好的 小弟

编辑:好的,现在我更困惑了。在 PowerShell 5.1 控制台中运行上述命令时,它按预期工作。将其放入脚本文件并执行时,它不会。

EDIT 2:更多信息,如果脚本文件以 UTF-8 编码保存,则会出现错误。如果它保存在另一种编码中(例如 Notepad++ 的 ANSI),它可以工作。为什么脚本文件的编码会改变脚本本身的行为?如何防止这种情况并确保获得一致的结果?

【问题讨论】:

  • 好像powershell被编码了两次
  • 我无法重现这一点,我在 PowerShell 5.1、7.1 和 7.2 中都得到了61c3b6c39f。你用的是哪个版本?

标签: java .net powershell utf-8


【解决方案1】:

尝试在 Notepad++ 中将您的脚本文件转换为UTF-8-BOM 编码并运行它。 PowerShell 5 的默认编码是Western European (Windows) (windows-1252),所以当您的脚本文件中没有 BOM 时,它会将其读取为 UTF-16,因此是双长度字符串。

PowerShell 7 中的默认编码是UTF-8,所以应该没问题。

您可以像这样检查不同 powershell 版本的默认编码:

PS> [System.Text.Encoding]::Default

您还可以指定所需的字符以避免在没有 BOM 的文件中出现此问题:

$str = [char]0x0061 + [char]0x00F6 + [char]0x00DF

Write-Output $(([System.Text.Encoding]::UTF8.GetBytes($str) | ForEach-Object ToString X2) -join '')

【讨论】:

  • 谢谢,这行得通!脚本文件本身的编码会修改其行为仍然很奇怪...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-02
  • 2016-02-17
  • 1970-01-01
  • 2018-05-11
  • 2017-02-08
  • 2011-03-02
  • 1970-01-01
相关资源
最近更新 更多