共享一堆位操作相关的方法:
// ----------------------------------------------------------------------- // <copyright file="UInt64MaskHelper.cs" author="Yaping Xin"> // // // File Name : UInt64MaskHelper.cs // Description : Helper class to support UInt64 bit mask. // Project Title : UInt64MaskHelper // Author(s) : Yaping Xin // Code Review Done : // Modification History: Created at Aug 10, 2012 // // </copyright> // ----------------------------------------------------------------------- namespace BitsHelper { /// <summary> /// Helper class to support UInt64 bit mask. /// </summary> public static class UInt64MaskHelper { #region Constant definition /// <summary> /// Constant definition of max avaiable bytes length. /// </summary> public const int MaxBytesLength = 8; /// <summary> /// Constant definition bits count within a byte /// </summary> public const int ByteBitsCount = 8; #endregion Constant definition #region Useful Bytes/Bits static readonly array definition /// <summary> /// Array of UInt64 byte mask values. /// </summary> private static readonly ulong[] U64ByteMaskValues = new ulong[] { 0x00000000000000FF, 0x000000000000FF00, 0x0000000000FF0000, 0x00000000FF000000, 0x000000FF00000000, 0x0000FF0000000000, 0x00FF000000000000, 0xFF00000000000000 }; /// <summary> /// Array of max values storaged in different amount of bytes within UInt64 scope. /// </summary> private static readonly ulong[] U64BytesMaxValues = new ulong[] { 0x00000000000000FF, 0x000000000000FFFF, 0x0000000000FFFFFF, 0x00000000FFFFFFFF, 0x000000FFFFFFFFFF, 0x0000FFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }; /// <summary> /// Array of shift values to specific byte lowest bit position. /// </summary> private static readonly byte[] BytePositionShiftValues = new byte[] { 0, 8, 16, 24, 32, 40, 48, 56 }; /// <summary> /// Array of byte bit mask values. /// </summary> private static readonly byte[] ByteBitMaskValues = new byte[] { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; /// <summary> /// Array of byte bit mask values. /// </summary> private static readonly byte[] ByteBitOffMaskValues = new byte[] { 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F }; #endregion Useful Bytes/Bits static readonly array definition #region Enumeration definition /// <summary> /// Enumeration definition of the error code /// </summary> public enum ErrorCode : uint { /// <summary>No error occurs</summary> OK = 0, /// <summary>Argument is Null</summary> ArgumentIsNull = 1, /// <summary>Argument is out of range</summary> ArgumentOutOfRange = 2, } #endregion Enumeration definition #region Encoding methods (numeric value to bytes/bits) /// <summary> /// Gets the bytes array to storage the specific UInt64 value. /// </summary> /// <param name="value">The specific UInt64 value.</param> /// <returns>The bytes array.</returns> public static byte[] GetBytes(ulong value) { byte[] result = new byte[MaxBytesLength]; ulong maskResult = value & U64ByteMaskValues[0]; result[0] = (byte)maskResult; for (int i = 1; i < MaxBytesLength; i++) { maskResult = value & U64ByteMaskValues[i]; result[i] = (byte)(maskResult >> BytePositionShiftValues[i]); } return result; } /// <summary> /// Gets the byte at specific position from the UInt64 value. /// Notes: this function will not return detailed error code while error occurs. /// </summary> /// <param name="value">The UInt64 value.</param> /// <param name="bytePosition">The byte position.</param> /// <param name="result">The byte to get.</param> /// <returns> /// <c>true</c> indicates no error occurs during calculating; /// <c>fasle</c> indicates error occurs. /// </returns> public static bool GetByte(ulong value, int bytePosition, out byte result) { ErrorCode errorCode; return UInt64MaskHelper.GetByte(value, bytePosition, out result, out errorCode); } /// <summary> /// Gets the byte at specific position from the UInt64 value. /// </summary> /// <param name="value">The UInt64 value.</param> /// <param name="bytePosition">The byte position.</param> /// <param name="result">The byte to get.</param> /// <param name="errorCode">The error code. /// Will be set to ErrorCode.OK if no error occurs.</param> /// <returns> /// <c>true</c> indicates no error occurs during calculating; /// <c>fasle</c> indicates error occurs, and detailed error is wrote in errorCode output parameter. /// </returns> public static bool GetByte( ulong value, int bytePosition, out byte result, out ErrorCode errorCode) { if (bytePosition < 0 || bytePosition >= MaxBytesLength) { result = 0; errorCode = ErrorCode.ArgumentOutOfRange; return false; } ulong maskResult; if (bytePosition == 0) { maskResult = value & U64ByteMaskValues[0]; goto EXIT_PASS; } maskResult = value & U64ByteMaskValues[bytePosition]; maskResult >>= BytePositionShiftValues[bytePosition]; EXIT_PASS: result = (byte)maskResult; errorCode = ErrorCode.OK; return true; } /// <summary> /// Gets the bit at specific position from the byte value. /// Notes: this function will not return detailed error code while error occurs. /// </summary> /// <param name="value">The byte value.</param> /// <param name="bitPosition">The bit position.</param> /// <param name="result">The bit (0 or 1) to get.</param> /// <returns> /// <c>true</c> indicates no error occurs during calculating; /// <c>fasle</c> indicates error occurs. /// </returns> public static bool GetBit(byte value, int bitPosition, out byte result) { ErrorCode errorCode; return UInt64MaskHelper.GetBit(value, bitPosition, out result, out errorCode); } /// <summary> /// Gets the bit at specific position from the byte value. /// </summary> /// <param name="value">The byte value.</param> /// <param name="bitPosition">The bit position.</param> /// <param name="result">The bit (0 or 1) to get.</param> /// <param name="errorCode">The error code. /// Will be set to ErrorCode.OK if no error occurs.</param> /// <returns> /// <c>true</c> indicates no error occurs during calculating; /// <c>fasle</c> indicates error occurs, and detailed error is wrote in errorCode output parameter. /// </returns> public static bool GetBit( byte value, int bitPosition, out byte result, out ErrorCode errorCode) { if (bitPosition < 0 || bitPosition >= ByteBitsCount) { result = 0; errorCode = ErrorCode.ArgumentOutOfRange; return false; } if (bitPosition == 0) { result = (byte)(value & ByteBitMaskValues[0]); errorCode = ErrorCode.OK; return true; } byte maskResult = (byte)(value & ByteBitMaskValues[bitPosition]); result = maskResult >>= bitPosition; errorCode = ErrorCode.OK; return true; } #endregion Encoding methods (numeric value to bytes/bits) #region Decoding methods (bytes/bits to numeric value) /// <summary> /// Gets the UInt64 value from bytes array. /// Notes: this function will not return detailed error code while error occurs. /// </summary> /// <param name="bytes">The bytes array.</param> /// <param name="value">The UInt64 value.</param> /// <returns> /// <c>true</c> indicates no error occurs during calculating; /// <c>fasle</c> indicates error occurs. /// </returns> public static bool GetUInt64(byte[] bytes, out ulong value) { ErrorCode errorCode; return UInt64MaskHelper.GetUInt64(bytes, out value, out errorCode); } /// <summary> /// Gets the UInt64 value from bytes array. /// </summary> /// <param name="bytes">The bytes array.</param> /// <param name="value">The UInt64 value.</param> /// <param name="errorCode">The error code. /// Will be set to ErrorCode.OK if no error occurs.</param> /// <returns> /// <c>true</c> indicates no error occurs during calculating; /// <c>fasle</c> indicates error occurs, and detailed error is wrote in errorCode output parameter. /// </returns> public static bool GetUInt64(byte[] bytes, out ulong value, out ErrorCode errorCode) { if (bytes == null || bytes.Length == 0) { errorCode = ErrorCode.ArgumentIsNull; value = 0; return false; } if (bytes.Length > MaxBytesLength) { errorCode = ErrorCode.ArgumentOutOfRange; value = 0; return false; } ulong result = bytes[0]; ulong byteValue; if (bytes.Length > 1) { for (int i = 1; i < bytes.Length; i++) { byteValue = bytes[i]; byteValue <<= BytePositionShiftValues[i]; result += byteValue; } } value = result; errorCode = ErrorCode.OK; return true; } #endregion Decoding methods (bytes/bits to numeric value) #region Set bit value /// <summary> /// Sets bit value at specific bit position within the raw byte. /// Notes: this function will not return detailed error code while error occurs. /// </summary> /// <param name="rawByte">The raw byte.</param> /// <param name="bitPosition">The bit position.</param> /// <param name="bitValue">if set to <c>true</c> [bit value].</param> /// <returns> /// <c>true</c> indicates no error occurs during calculating; /// <c>fasle</c> indicates error occurs. /// </returns> public static bool SetBit(ref byte rawByte, int bitPosition, bool bitValue) { ErrorCode errorCode; return UInt64MaskHelper.SetBit(ref rawByte, bitPosition, bitValue, out errorCode); } /// <summary> /// Sets bit value at specific bit position within the raw byte. /// </summary> /// <param name="rawByte">The raw byte.</param> /// <param name="bitPosition">The bit position.</param> /// <param name="bitValue"><c>true</c> indicates set bit value to 1; /// otherwise set bit value to 0.</param> /// <param name="errorCode">The error code. /// Will be set to ErrorCode.OK if no error occurs.</param> /// <returns> /// <c>true</c> indicates no error occurs during calculating; /// <c>fasle</c> indicates error occurs, and detailed error is wrote in errorCode output parameter. /// </returns> public static bool SetBit(ref byte rawByte, int bitPosition, bool bitValue, out ErrorCode errorCode) { if (bitPosition < 0 || bitPosition >= ByteBitsCount) { errorCode = ErrorCode.ArgumentOutOfRange; return false; } if (bitValue) { rawByte |= ByteBitMaskValues[bitPosition]; } else { rawByte &= ByteBitOffMaskValues[bitPosition]; } errorCode = ErrorCode.OK; return true; } #endregion Set bit value } }