ZibraHash128.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. using System.Runtime.InteropServices;
  2. using UnityEngine;
  3. namespace com.zibra.common.Utilities
  4. {
  5. // Basically CRC128
  6. [StructLayout(LayoutKind.Sequential)]
  7. internal class ZibraHash128
  8. {
  9. private ulong M0;
  10. private ulong M1;
  11. private const ulong POLYNOMIAL0 = 0x8000000000000000ul;
  12. private const ulong POLYNOMIAL1 = 0x0000000000000003ul;
  13. public void Init()
  14. {
  15. M0 = 0;
  16. M1 = 0;
  17. }
  18. public void Append(bool input)
  19. {
  20. ulong bit = (input ? 1ul : 0ul) ^ (M1 & 1ul);
  21. // right shifting 128 bit hash
  22. M1 >>= 1;
  23. M1 += (M0 & 1) * 0x8000000000000000ul;
  24. M0 >>= 1;
  25. M0 ^= bit * POLYNOMIAL0;
  26. M1 ^= bit * POLYNOMIAL1;
  27. }
  28. public void Append(int input)
  29. {
  30. for (int i = 0; i < sizeof(int) * 8; i++)
  31. {
  32. Append((input & 1) != 0);
  33. input >>= 1;
  34. }
  35. }
  36. public void Append(Color32[] input)
  37. {
  38. foreach (Color32 color in input)
  39. {
  40. Append(color.r);
  41. Append(color.g);
  42. Append(color.b);
  43. Append(color.a);
  44. }
  45. }
  46. public static bool operator ==(ZibraHash128 hash1, ZibraHash128 hash2)
  47. {
  48. if (hash1 is null && hash2 is null)
  49. return true;
  50. if (hash1 is null || hash2 is null)
  51. return false;
  52. return hash1.M0 == hash2.M0 && hash1.M1 == hash2.M1;
  53. }
  54. public static bool operator !=(ZibraHash128 hash1, ZibraHash128 hash2)
  55. {
  56. if (hash1 is null && hash2 is null)
  57. return false;
  58. if (hash1 is null || hash2 is null)
  59. return true;
  60. return hash1.M0 != hash2.M0 || hash1.M1 != hash2.M1;
  61. }
  62. public static bool operator<(ZibraHash128 hash1, ZibraHash128 hash2)
  63. {
  64. if (hash1 is null && hash2 is null)
  65. return false;
  66. if (hash1 is null || hash2 is null)
  67. return hash1 is null;
  68. return hash1.M0 < hash2.M0 || (hash1.M0 == hash2.M0 && hash1.M1 < hash2.M1);
  69. }
  70. public static bool operator>(ZibraHash128 hash1, ZibraHash128 hash2)
  71. {
  72. if (hash1 is null && hash2 is null)
  73. return false;
  74. if (hash1 is null || hash2 is null)
  75. return hash2 is null;
  76. return hash1.M0 > hash2.M0 || (hash1.M0 == hash2.M0 && hash1.M1 > hash2.M1);
  77. }
  78. public override bool Equals(object obj)
  79. {
  80. if ((obj == null) || !typeof(ZibraHash128).Equals(obj.GetType()))
  81. {
  82. return false;
  83. }
  84. ZibraHash128 p = (ZibraHash128)obj;
  85. return this == p;
  86. }
  87. public override int GetHashCode()
  88. {
  89. const uint MAX_INT = 0xFFFFFFFF;
  90. ulong hash = ((M0 >> 16) & MAX_INT) ^ (M0 & MAX_INT) ^ ((M1 >> 16) & MAX_INT) ^ (M1 & MAX_INT);
  91. return (int)hash;
  92. }
  93. }
  94. }