2016-08-16 41 views
1

我在C中有下面的代碼,它將根據輸入的序列號生成密鑰。C#中的字符與C溢出的按位補碼

unsigned int32 passkey(unsigned int32 snumber) 
{ 
    char snstring[11]; 
    unsigned int32 pwd; 
    int i = 0; 
    itoa(snumber,10,snstring); 
    do{ 
     snstring[i+1] -= '0'; 
     snstring[i] = ~snstring[i+1]; 
     snstring[i] &= 0x07; 
     i++; 
    }while(i < 9); 
    snstring[9] <<= 1; 
    snstring[9] &= 0x07; 
    pwd = atoi32(snstring); 
    return (pwd); 
} 

我需要將其轉換成C#代碼,我曾嘗試以下操作:

private uint ComputeKey(uint snumber) 
     { 
      char[] snstring = new char[11]; 
      UInt32 pwd; 
      int i = 0; 
      snstring = snumber.ToString().ToCharArray(); 

      do 
      { 
       snstring[i + 1] = Convert.ToChar(snstring[i + 1] - '0'); 
       snstring[i] = Convert.ToChar(~Convert.ToInt32(snstring[i + 1])); 
       snstring[i] &= Convert.ToChar(Convert.ToInt32(0x07)); 
       i++; 
      } while (i < 9); 
      snstring[9] <<= 1; 
      snstring[9] &= Convert.ToChar(0x07); 
      pwd = Convert.ToUInt32(snstring); 
      return (pwd); 
     } 

程序在snstring[i] = Convert.ToChar(~Convert.ToInt32(snstring[i + 1]));此行拋出異常。

另一個值得注意的行爲是例如我已經輸入作爲

然後,在這條線的snstring[i] = Convert.ToChar(~Convert.ToInt32(snstring[i + 1]));snstring[i+1]'\u0005' 而且它拋出OverflowException異常是未處理的。

我不知道我該怎麼做,任何幫助表示讚賞。

+0

的'〜Convert.ToInt32結果(snstring第[i + 1])'無法轉換爲char,因爲它在該範圍之外。處理它。 –

+0

停止在'int'和'char'之間來回轉換。轉換爲'int'一次,應用所有位,然後轉換回來。 – Phylogenesis

+0

爲什麼不使用良好的舊工作c函數?請參閱:http://stackoverflow.com/a/11593657/3989673 – bigahega

回答

1

我已經完成了一個類似的任務,即將一個數字作爲輸入,並在C#中完成您的代碼。我將字符串作爲輸入並返回字符串。 下面是代碼:

private string ComputeKey(string serialnumber) 
     { 
      if (string.IsNullOrEmpty(serialnumber)) 
      { 
       throw new Exception("Cannot generate a key from a null or empty string"); 
      } 

      serialnumber += '\0'; 
      var length = serialnumber.Length; 
      byte[] snbytes = Encoding.UTF8.GetBytes(serialnumber); 
      for (int i = 0; i < length - 1; i++) 
      { 
       snbytes[i + 1] -= 0x30; 
       snbytes[i] = (byte)~snbytes[i + 1]; 
       snbytes[i] &= 0x07; 
      } 
      snbytes[length - 1] <<= 1; 
      snbytes[length - 1] &= 0x07; 

      var sb = new StringBuilder(); 
      for (int j = 0; j < length - 1; j++) 
      { 
       sb.Append(snbytes[j].ToString()); 
      } 

      return sb.ToString(); 
     } 
1

當你翻轉32位int的位代表一個char(它總是有一個字節的C)時,最後的三個字節設置爲0xFF。然而,C高興地剔除了分配給char的高字節,而C#的轉換器拋出異常。

您可以通過就地轉換使用強制轉換爲匹配C做什麼解決這個問題:

snstring[i+1] -= '0'; 
snstring[i] = (char)(~snstring[i+1] & 0x07); 

從本質上講,投告訴C#明確做C不用默認情況下,同樣的事情。

+1

由於整數升級,最終在C中將高位字節設置爲0xFF。但是C很寬鬆,並且允許賦值直接執行隱式轉換回左值類型,而不產生任何診斷。簡單地說,堅固的C代碼也應該在'〜'之後直接隱式轉換爲預期類型,例如'(unsigned char)〜snstring [i + 1]'。 (你不想在C中使用'char',因爲它具有很差的簽名。) – Lundin

+0

修正了,謝謝! – dasblinkenlight