title: Is it legitimate to use LayoutKind.Explicit to get around using "unsafe" pointers?
body: <p>I have code which does XOR on blocks of data using pointers, which is fast, but I'd like to get rid of the "unsafe" requirement on the assembly.  If I change it to use LayoutKind.Explicit and overlay a "ulong[]" on top of a "byte[]", I'm basically doing the same thing as I did with pointers, but it seems to be just as dangerous.  The main difference between these two is that the "Safe" version is about 1/2 the speed of the "Unsafe" version.</p>
  
  <p>Is this a legitimate way to get around having an "unsafe" assembly, or is accessing the byte[] 1 byte at a time the only legitimate way to do this in a safe manner?</p>
  
  <pre><code>private unsafe static void UnsafeEncode(
      byte[] buffer, int bufPos, ulong[] vector, int SectionLength, byte vectorIndex)
  {
      fixed (byte* p = &amp;buffer[bufPos])
      {
          ulong* pCur = (ulong*)p;
          ulong* pEnd = pCur + SectionLength;
          while (pCur &lt; pEnd)
          {
              *pCur ^= vector[vectorIndex++];
              pCur++;
          }
      }
  }
  
  [StructLayout(LayoutKind.Explicit)]
  private struct ArrayOverlay
  {
      [FieldOffset(0)]
      public byte[] Bytes;
      [FieldOffset(0)]
      public ulong[] Longs;
  }
  
  private static void SafeEncode(
      byte[] buffer, int bufPos, ulong[] vector, int SectionLength, byte vectorIndex)
  {
      var overlay = new ArrayOverlay { Bytes = buffer };
      int shiftleft = (bufPos &amp; 7) &lt;&lt; 3;
      int pos = bufPos &gt;&gt; 3;
      if (shiftleft == 0)
      {
          for (int i = 0; i &lt; SectionLength; i++)
              overlay.Longs[i + pos] ^= vector[vectorIndex++];
      }
      else
      {
          int shiftright = (64 - shiftleft) &amp; 63;
          ulong oldVec = 0;
          for (int i = 0; i &lt; SectionLength; i++)
          {
              var vec = vector[vectorIndex++];
              overlay.Longs[i + pos] ^= (vec &lt;&lt; shiftleft) | (oldVec &gt;&gt; shiftright);
              oldVec = vec;
          }
          overlay.Longs[SectionLength + pos] ^= (oldVec &gt;&gt; shiftright);
      }
  }
  </code></pre>