2013-02-02 60 views
-2

这很简单,我希望。这些是由反斜杠\和C编译器分隔的20个十六进制值,确实使它们成为33个字符的字符串,因为\NUMBER是单个值\NUMBER+ALPHA = 2个字节以及\ALPHA+NUMBER 2个字节。我们可以在C中反转这个字符串吗?

char str[] = 
"\b3\bc\77\7\de\ed\44\93\75\ce\c0\9\19\59\c8\f\be\c6\30\6"; 
//when saved is 33 bytes 

我的问题是在它已经保存到磁盘上的33个字节,可我们(阅读后33个字节)改造,我们在C同样的演示?所以程序打印"\b3\bc\77\7\de\ed\44\93\75\ce\c0\9\19\59\c8\f\be\c6\30\6",这里的任何问题解决者?

"\b3\bc\77\7\de\ed\44\93\75\ce\c0\9\19\59\c8\f\be\c6\30\6"; 
//when read back program should output this^
+5

当然 - 为什么不呢?什么具体问题阻止你这样做? –

+0

它们不像您期望的那样被保存为十六进制值。这是肯定的一件事。 – nhahtdh

+0

你的问题是什么? – Arpit

回答

2

字符串字面您有:

"\b3\bc\77\7\de\ed\44\93\75\ce\c0\9\19\59\c8\f\be\c6\30\6" 

将根据C89产生不确定的行为(不知道是否为C89源是可以信任的,但我的下面点仍持有),并定义执行,行为根据C11标准。具体而言,\d,\e,\9,\c是未在标准中定义的转义序列。 gcc不会抱怨\e,因为它是代表ESC的GNU扩展。

由于存在实现定义的行为,因此我们有必要了解您使用的编译器,结果可能会有所不同。

另一件事是,你没有显示明确,你知道编译后的字符串的内容。 (更清晰的显示方式应该包括字符串在内存中的内容的十六进制转储,并显示如何识别转义序列)。

这是看起来如何样十六进制字符串是由编译器识别:拐弯抹角

String: \b 3 \b c \77 \7 \d e \e d \44 \9 3 \75 \c e \c 0 \9 \1 9 \5 9 \c 8 \f \b e \c 6 \20 \6 
Char: \b 3 \b c \77 \7 d e \e d \44 \9 3 \75 c e c 0 9 \1 9 \5 9 c 8 \f \b e c 6 \20 \6 
Hex: 08 33 08 63 3f 07 64 65 1b 64 24 39 33 3d 63 65 63 30 39 01 39 05 39 63 38 0c 08 65 63 36 18 06 00 

够了跳动。假设您正在使用gcc编译代码(忽略警告)。当代码运行时,使用fwrite将整个char[]写入文件。我还假设在源代码中只使用小写字符。

您应该将所有可能的转义序列\xy映射为2位十六进制数字到1或2个字节的序列。有没有那么多的人,你可以写一个程序来模拟编译器的行为:

  • 如果x是任何的abf(如\n其他转义序列不是十六进制数字)和e(由于GNU扩展)。它映射到特殊字符。
  • (如果你在源代码中使用大写字母,也注意\E映射到ESC)
  • 如果xy形成一个有效的八进制序列。它被映射到具有相应值的字符。
  • 如果x形成有效的八进制序列。它被映射到具有相应值的字符。
  • 否则,x保持不变。
  • 如果没有消耗y,则y保持不变。

请注意,实际的char可能来自两种不同的方式。例如,\f\14将映射到相同的char。在这种情况下,可能无法取回源中的字符串。你能做的最多的是猜测源代码中的字符串是什么。

以您的字符串为例,开头的0833可以来自\b3,但它也可以来自\10\63

使用map生成,有些情况下映射清晰:大于3f的十六进制不能来自八进制转义序列,并且必须来自原始字符串中字符的直接解释。从这里,你知道如果遇到e,它必须是第二个字符看起来像十六进制序列。

您可以使用地图作为指导,并将模拟作为一种方法来检查地图是否会产生回ASCII码。在不了解源代码中声明的字符串的任何信息的情况下,可以派生的最多是源代码中原始(已损坏)字符串的候选列表。如果您至少知道源代码中字符串的长度,则可以缩小候选列表的大小。

+0

我认为OP只是误解了如何写十六进制转义...... –

+0

@JimGarrison:不确定OP想要什么,因为它首先是一个非常奇怪的问题。你看看这个问题的评论吗? – nhahtdh

+0

回复高度赞赏亲爱@nhahtdh –

相关问题