title: .Net 4.6 breaks XOR cipher pattern?
body: <p>In .NET 4.5 this cipher worked perfectly on 32 and 64 bit architecture. Switching the project to .NET 4.6 breaks this cipher completely in 64-bit, and in 32-bit there's an <strong><em>odd</em></strong> patch for the issue.</p>
  
  <p>In my method "DecodeSkill", <em>SkillLevel is the only part that breaks on .NET 4.6.</em>
  The variables used here are read from a network stream and are encoded.</p>
  
  <p>DecodeSkill (Always returns the proper decoded value for <em>SkillLevel</em>)</p>
  
  <pre><code>    private void DecodeSkill()
      {
          SkillId = (ushort) (ExchangeShortBits((SkillId ^ ObjectId ^ 0x915d), 13) + 0x14be);
          SkillLevel = ((ushort) ((byte)SkillLevel ^ 0x21));
          TargetObjectId = (ExchangeLongBits(TargetObjectId, 13) ^ ObjectId ^ 0x5f2d2463) + 0x8b90b51a;
          PositionX = (ushort) (ExchangeShortBits((PositionX ^ ObjectId ^ 0x2ed6), 15) + 0xdd12);
          PositionY = (ushort) (ExchangeShortBits((PositionY ^ ObjectId ^ 0xb99b), 11) + 0x76de);
      }
  </code></pre>
  
  <p>ExchangeShortBits</p>
  
  <pre><code>    private static uint ExchangeShortBits(uint data, int bits)
      {
          data &amp;= 0xffff;
          return (data &gt;&gt; bits | data &lt;&lt; (16 - bits)) &amp; 65535;
      }
  </code></pre>
  
  <p>DecodeSkill (<em>Patched</em> for .NET 4.6 32-bit, notice "var patch = SkillLevel")</p>
  
  <pre><code>    private void DecodeSkill()
      {
          SkillId = (ushort) (ExchangeShortBits((SkillId ^ ObjectId ^ 0x915d), 13) + 0x14be);
          var patch = SkillLevel = ((ushort) ((byte)SkillLevel ^ 0x21));
          TargetObjectId = (ExchangeLongBits(TargetObjectId, 13) ^ ObjectId ^ 0x5f2d2463) + 0x8b90b51a;
          PositionX = (ushort) (ExchangeShortBits((PositionX ^ ObjectId ^ 0x2ed6), 15) + 0xdd12);
          PositionY = (ushort) (ExchangeShortBits((PositionY ^ ObjectId ^ 0xb99b), 11) + 0x76de);
      }
  </code></pre>
  
  <p>Assigning the variable as SkillLevel, in 32-bit only, will cause SkillLevel to always be the correct value. Remove this patch, and the value is always incorrect. In 64-bit, this is always incorrect even with the patch.</p>
  
  <p>I've tried using MethodImplOptions.NoOptimization and MethodImplOptions.NoInlining on the decode method thinking it would make a difference.</p>
  
  <p>Any ideas to what would cause this?</p>
  
  <p>Edit:
  I was asked to give an example of input, good output, and bad output.
  This is from an actual usage scenario, values were sent from the client and properly decoded by the server using the "patch" on .NET 4.6.</p>
  
  <p>Input:</p>
  
  <pre><code>ObjectId = 1000001
  
  TargetObjectId = 2778236265
  PositionX = 32409
  PositionY = 16267
  SkillId = 28399
  SkillLevel = 8481
  </code></pre>
  
  <p>Good Output</p>
  
  <pre><code>TargetObjectId = 0
  PositionX = 302
  PositionY = 278
  SkillId = 1115
  SkillLevel = 0
  </code></pre>
  
  <p>Bad Output</p>
  
  <pre><code>TargetObjectId = 0
  PositionX = 302
  PositionY = 278
  SkillId = 1115
  SkillLevel = 34545
  </code></pre>
  
  <p>Edit#2:</p>
  
  <p>I should include this part, definitely an important part to this.</p>
  
  <p>EncodeSkill (<strong><em>Timestamp</em></strong> is Environment.TickCount)</p>
  
  <pre><code>     private void EncodeSkill()
      {
          SkillId = (ushort) (ExchangeShortBits(ObjectId - 0x14be, 3) ^ ObjectId ^ 0x915d);
          SkillLevel = (ushort) ((SkillLevel + 0x100*(Timestamp%0x100)) ^ 0x3721);
          Arg1 = MathUtils.BitFold32(SkillId, SkillLevel);
          TargetObjectId = ExchangeLongBits(((TargetObjectId - 0x8b90b51a) ^ ObjectId ^ 0x5f2d2463u), 19);
          PositionX = (ushort) (ExchangeShortBits((uint) PositionX - 0xdd12, 1) ^ ObjectId ^ 0x2ed6);
          PositionY = (ushort) (ExchangeShortBits((uint) PositionY - 0x76de, 5) ^ ObjectId ^ 0xb99b);
      }
  </code></pre>
  
  <p>BitFold32</p>
  
  <pre><code>    public static int BitFold32(int lower16, int higher16)
      {
          return (lower16) | (higher16 &lt;&lt; 16);
      }
  </code></pre>
  
  <p>ExchangeLongBits</p>
  
  <pre><code>    private static uint ExchangeLongBits(uint data, int bits)
      {
          return data &gt;&gt; bits | data &lt;&lt; (32 - bits);
      }
  </code></pre>