2013-02-02 97 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 –

相關問題