如何修复损坏的 shift-JIS 文件名?

Hic*_*cup 4 filenames shift-jis windows-8.1

我在 ANSI 中有一些带有 shift-jis 文件名的文件。例如

home_03@‚¢ƒgƒ‰ƒ“ƒNŠJ‚¢‚½Aƒtƒ@ƒCƒ‹—L‚è 
Run Code Online (Sandbox Code Playgroud)

什么时候他们应该像换班一样

home_03@????????????????
Run Code Online (Sandbox Code Playgroud)

这是因为我使用的存档提取器不支持 shift-jis。那真的没办法了。但是有没有办法修复我提取的文件的文件名?

编辑:

另一个例子

Ší‹ï‘ä@ƒXƒpƒi
Run Code Online (Sandbox Code Playgroud)

应该

???@???
Run Code Online (Sandbox Code Playgroud)

Bob*_*Bob 6

由于您使用的是 Windows,因此 PowerShell 可能是最简单的方法。

现在,PowerShell 在内部对其字符串使用 UTF-16,因此转换将涉及四个步骤:

  1. 将文件系统中不正确的文件名读入 PS(内部表示为 UTF-16 字符串)
  2. 告诉 PS 将字符串转换为原始字节数组,就像字符串是 <不正确的编码> 一样。我们不能直接使用 PS 字符串(因为它是 UTF-16)。
  3. 告诉 PS 将字节数组转换回字符串,将其解释为 <正确编码>。这将使用解释为 Shift-JIS 的原始字节的 UTF-16 字符串。
  4. 重命名文件

让我们从定义编码开始。就您而言,我猜您的来源是 Windows-1252(西方/英语 Windows 的默认非 Unicode 代码页)。

$srcEnc = [System.Text.Encoding]::GetEncoding("Windows-1252")
$destEnc = [System.Text.Encoding]::GetEncoding("Shift-JIS")
Run Code Online (Sandbox Code Playgroud)

您也可以使用[System.Text.Encoding]::Default获取当前系统代码页,但我更喜欢明确表示。

然后我们应用转换步骤:

$newName = $destEnc.GetString($srcEnc.GetBytes($oldName))
Run Code Online (Sandbox Code Playgroud)

在您的示例中,home_03@‚¢ƒgƒ‰ƒ“ƒNŠJ‚¢‚½Aƒtƒ@ƒCƒ‹—L‚è变为home_03@?????????A??????. 虽然这与您的示例结果不同(请参阅底部的注释),但它与我从http://string-functions.com/encodedecode.aspx的 Windows-1252 => Shift-JIS获得的结果相匹配。如果这是不正确的,您可能需要反复试验,直到找到正确的源和目标编码。

将它与标准循环放在一起:

$srcEnc = [System.Text.Encoding]::GetEncoding("Windows-1252")
$destEnc = [System.Text.Encoding]::GetEncoding("Shift-JIS")
Get-ChildItem | %{Rename-Item -LiteralPath "$_" "$($destEnc.GetString($srcEnc.GetBytes($_.Name)))"}
Run Code Online (Sandbox Code Playgroud)

或者,如果您更喜欢递归到子目录中:

$srcEnc = [System.Text.Encoding]::GetEncoding("Windows-1252")
$destEnc = [System.Text.Encoding]::GetEncoding("Shift-JIS")
Get-ChildItem -Recurse | %{Rename-Item -LiteralPath "$_" "$($destEnc.GetString($srcEnc.GetBytes($_.Name)))"}
Run Code Online (Sandbox Code Playgroud)

如果您想避免重命名目录,请添加-FileGet-ChildItem


看起来您的示例包含两个在 Windows-1252 中无效的字符,并且在您发布问题时可能会被删除(基于使用示例输出反转过程)。有一个1440x90)的第一间@Â,和1290x81之间)½A。为了方便其他人进行测试,这是原始字节的 base64 编码版本:aG9tZV8wM0CQwoKig2eDiYOTg06KSoKigr2BQYN0g0CDQ4OLl0yC6A==.


另请注意,当源文件名或目标文件名中存在 Windows 认为无效的字符时,这将不起作用。特别是在源文件名中,因为您的提取工具可能会在提取时不可恢复地损坏名称(通过删除与无效字符对应的字节,例如?\错误编码)。在这些情况下,您唯一可以做的就是使用完全避免此问题的替代提取工具。