文件名中的0x202A:为什么?

时间:2014-06-04 12:47:10

标签: c# windows unicode copy-paste control-characters

我最近需要在varbinary图像上用SQL做一个isnull 到目前为止(ab)正常。 我很快写了一个C#程序,从我的桌面读取文件no_image.png,并将字节输出为十六进制字符串。

该计划就是这样开始的:

byte[] ba = System.IO.File.ReadAllBytes(@"‪D:\UserName\Desktop\no_image.png");
Console.WriteLine(ba.Length);
// From here, change ba to hex string

因为我之前曾经无数次使用过readallbytes,所以我觉得没什么大不了的。
令我惊讶的是,我得到了一个" NotSupported" ReadAllBytes上的异常。

我发现问题在于,当我右键单击该文件时,转到选项卡"安全",然后复制粘贴对象名称(在右侧开始标记并且向左移动不准确),这种情况发生了。

它只发生在Windows 8.1(可能是8)上,但不会发生在Windows 7上。

202A

当我输出有问题的字符串时:

public static string ToHexString(string input)
{
    string strRetVal = null;
    System.Text.StringBuilder sb = new System.Text.StringBuilder();

    foreach (char c in input)
    {
        sb.Append(((int)c).ToString("X2"));
    }

    strRetVal = sb.ToString();
    sb.Length = 0;
    sb = null;

    return strRetVal;
} // End Function ToHexString

string str = ToHexString(@"‪D:\UserName\Desktop\cookie.png");
string strRight = " (" + ToHexString(@"D:\UserName\Desktop\cookie.png") + ")"; // Correct value, for comparison

string msg = str + Environment.NewLine + "  " + strRight;
Console.WriteLine(msg);

我明白了:

202A443A5C557365724E616D655C4465736B746F705C636F6F6B69652E706E67
   (443A5C557365724E616D655C4465736B746F705C636F6F6B69652E706E67)

首先,当我在ascii中查找20 2A时,它的[空格] + *

由于我没有看到太空或星星,当我谷歌20 2A时,我得到的第一件事就是德国刑法第202a段 http://dejure.org/gesetze/StGB/202a.html

但我认为这是一个不幸的巧合,它实际上是unicode控制角色' LEFT-TO-RIGHT EMBEDDING' (U + 202A) http://www.fileformat.info/info/unicode/char/202a/index.htm

这是一个错误,还是一个功能?
我的猜测是,它是一个有缺陷的功能。

3 个答案:

答案 0 :(得分:3)

包含RLO / LRO覆盖的文件名通常由恶意软件创建。例如。 “exe” read backwards spells “malware”。您可能有受感染的主机,或者.png的来源已被感染。

答案 1 :(得分:3)

问题是该字符串根本不以字母D开头 - 它看起来就像它一样。

看来该字符串在源文件中是硬编码的。

如果是这种情况,那么您已从安全对话框中粘贴了该字符串。你不知道,你粘贴的字符串以LRO字符开头。这是一个不可见的字符,它不会占用空间,但会告诉渲染器从左到右渲染字符,忽略通常的渲染。

您只需要删除该字符。

要执行此操作,请将光标放在字符串中的D之后。使用退格键或从左侧删除键<x]删除D。再次使用该键删除不可见的LRO字符。再次删除"。现在重新输入"D

类似的问题可能发生在字符串来自哪里 - 例如来自用户输入,命令行,脚本文件等。

注意:安全对话框显示以LRO字符开头的文件名,以确保字符以从左到右的顺序显示,这对于确保在正确理解层次结构时是必需的。使用RTL字符。例如阿拉伯语中的文件名c:\folder\path\to\file可能为c:\folder\مسار/إلى/ملف。 “gotcha”是在另一个方向读取的阿拉伯语部分,因此根据谷歌翻译的“路径”一词是مسار,这是最右边的字,使它出现的是它是否是最后一个元素路径,实际上它是紧跟在“c:\ folder \”之后的元素。

由于安全对象路径的层次结构与RTL文本布局规则冲突,因此安全对话框始终以LTR模式显示RTL文本。这意味着安全选项卡上的阿拉伯语单词将被修改(字母顺序错误)。 (想象一下,好像它说“elif ot htap”)。所以意义只是可辨别的,但从安全的角度来看,安全语义得以保留。

答案 2 :(得分:0)

这个问题困扰了我很多,确定性函数如何为相同的输入提供2个不同的结果?经过一些测试,结果证明答案很简单。

如果你在调试器中查看它,你会看到&#39; D&#39; @"‪D:\UserName\Desktop\cookie.png"中的char(首次使用Hex函数)与@"D:\UserName\Desktop\cookie.png"中的char(第二次使用)不同。

您必须使用其他类似D&#39;的字符,可能是通过不需要的键盘快捷键或弄乱您的Visual Studio字符编码。

它看起来完全一样,但实际上,在你的toHex函数中观察c变量并不是单一的char 9try事件。

如果你改为正常的&#39; D&#39;在你的第一个例子中,它会正常工作。