2015-09-26 36 views
0

所以我一直在C#中編寫一個小字節密碼,並且一切都很順利,直到我試圖做一些循環來測試運行時性能。這是事情變得非常奇怪的地方。請允許我向您展示,而不是去解釋它,:For循環有意想不到的副作用

首先,這裏是工作代碼(註釋掉循環):

using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using DreamforceFramework.Framework.Cryptography; 

namespace TestingApp 
{ 
    static class Program 
    { 
     static void Main(string[] args) 
     { 

      string myData = "This is a test."; 
      byte[] myDataEncrypted; 
      string myDecryptedData = null; 
      Stopwatch watch = new Stopwatch(); 
      Console.WriteLine("Warming up for Encryption..."); 
      //for (int i = 0; i < 20; i++) 
      //{ 
      // // Warm up the algorithm for a proper speed benchmark. 
      // myDataEncrypted = DreamforceByteCipher.Encrypt(myData, "Dreamforce"); 
      //} 
      watch.Start(); 
      myDataEncrypted = DreamforceByteCipher.Encrypt(myData, "Dreamforce"); 
      watch.Stop(); 
      Console.WriteLine("Encryption Time: " + watch.Elapsed); 
      Console.WriteLine("Warming up for Decryption..."); 
      //for (int i = 0; i < 20; i++) 
      //{ 
      // // Warm up the algorithm for a proper speed benchmark. 
      // myDecryptedData = DreamforceByteCipher.Decrypt(myDataEncrypted, "Dreamforce"); 
      //} 
      watch.Reset(); 
      watch.Start(); 
      myDecryptedData = DreamforceByteCipher.Decrypt(myDataEncrypted, "Dreamforce"); 
      watch.Stop(); 
      Console.WriteLine("Decryption Time: " + watch.Elapsed); 
      Console.WriteLine(myDecryptedData); 
      Console.Read(); 
     } 
    } 
} 

和我ByteCipher(我非常錯誤後簡化IT最初出現是試圖查明問題):

using System; 
using System.IO; 
using System.Linq; 
using System.Security.Cryptography; 
using System.Text; 
using DreamforceFramework.Framework.Utilities; 

namespace DreamforceFramework.Framework.Cryptography 
{ 
    /// <summary> 
    /// DreamforceByteCipher 
    /// Gordon Kyle Wallace, "Krythic" 
    /// Copyright (C) 2015 Gordon Kyle Wallace, "Krythic" - All Rights Reserved 
    /// </summary> 
    public static class DreamforceByteCipher 
    { 

     public static byte[] Encrypt(string data, string password) 
     { 
      byte[] bytes = Encoding.UTF8.GetBytes(data); 
      string passwordHash = DreamforceHashing.GenerateSHA256(password); 
      byte[] hashedPasswordBytes = Encoding.ASCII.GetBytes(passwordHash); 
      int passwordShiftIndex = 0; 
      bool twistPath = false; 
      for (int i = 0; i < bytes.Length; i++) 
      { 
       int shift = hashedPasswordBytes[passwordShiftIndex]; 
       bytes[i] = twistPath 
        ? (byte)(
         (data[i] + (shift * i))) 
        : (byte)(
         (data[i] - (shift * i))); 
       passwordShiftIndex = (passwordShiftIndex + 1) % 64; 
       twistPath = !twistPath; 
      } 
      return bytes; 
     } 

     /// <summary> 
     /// Decrypts a byte array back into a string. 
     /// </summary> 
     /// <param name="data"></param> 
     /// <param name="password"></param> 
     /// <returns></returns> 
     public static string Decrypt(byte[] data, string password) 
     { 
      string passwordHash = DreamforceHashing.GenerateSHA256(password); 
      byte[] hashedPasswordBytes = Encoding.UTF8.GetBytes(passwordHash); 
      int passwordShiftIndex = 0; 
      bool twistPath = false; 
      for (int i = 0; i < data.Length; i++) 
      { 
       int shift = hashedPasswordBytes[passwordShiftIndex]; 
       data[i] = twistPath 
        ? (byte)(
         (data[i] - (shift * i))) 
        : (byte)(
         (data[i] + (shift * i))); 
       passwordShiftIndex = (passwordShiftIndex + 1) % 64; 
       twistPath = !twistPath; 
      } 
      return Encoding.ASCII.GetString(data); 
     } 
    } 
} 

隨着對註釋掉循環,這是我得到的輸出:

enter image description here

最後一行顯示所有內容均已成功解密。

現在......這是事情變得怪異的地方。如果您取消註釋for循環,並運行程序,這是輸出:

enter image description here

解密沒有工作。這絕對沒有意義,因爲保存解密數據的變量應該每次都要重寫。我在C#/。NET中遇到了導致這種奇怪行爲的錯誤嗎?

一個簡單的解決方案: http://pastebin.com/M3xa9yQK

+6

在'public static string Decrypt'你改變'data'。數組通過引用傳遞,所以下一次調用'Decrypt'來接收修改的'data'。 – GSerg

+0

@ M.kazemAkhgary它總是給出相同的結果。 – Krythic

+0

@GSerg Nit:數組/對象通過* reference-value *(或「通過[引用]的值調用」)進行傳遞,以便通過對象共享語義進行調用。 – user2864740

回答

12

Decrypt方法修改代替data輸入數組。因此,在數據不再加密之前,您只能使用任何給定的輸入字節數組調用Decrypt一次。以一個簡單的控制檯應用爲例:

class Program 
{ 
    public static void Main(string[] args) 
    { 
     var arr = new byte[] { 10 }; 
     Console.WriteLine(arr[0]); // prints 10 
     DoSomething(arr); 
     Console.WriteLine(arr[0]); // prints 11 
    } 

    private static void DoSomething(byte[] arr) 
    { 
     arr[0] = 11; 
    } 
} 

所以,要回答你的問題,不。你還沒有在.NET中發現錯誤。您在代碼中發現了一個非常簡單的錯誤。

+0

這就是它,代表我進行了一次小小的監督,謝謝。 – Krythic