HashAlgorithm.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. //
  2. // System.Security.Cryptography HashAlgorithm Class implementation
  3. //
  4. // Authors:
  5. // Matthew S. Ford ([email protected])
  6. //
  7. // Copyright 2001 by Matthew S. Ford.
  8. //
  9. using System.Security.Cryptography;
  10. namespace System.Security.Cryptography {
  11. public abstract class HashAlgorithm : ICryptoTransform {
  12. protected byte[] HashValue; // Caches the hash after it is calculated. Accessed through the Hash property.
  13. protected int HashSizeValue; // The size of the hash in bits.
  14. protected int State; // nonzero when in use; zero when not in use
  15. /// <summary>
  16. /// Called from constructor of derived class.
  17. /// </summary>
  18. protected HashAlgorithm () {
  19. }
  20. /// <summary>
  21. /// FIXME: Always true for hashes?
  22. /// Get whether or not the hash can transform multiple blocks at a time.
  23. /// </summary>
  24. [MonoTODO]
  25. public virtual bool CanTransformMultipleBlocks {
  26. get {
  27. return true;
  28. }
  29. }
  30. /// <summary>
  31. /// Computes the entire hash of all the bytes in the byte array.
  32. /// </summary>
  33. public virtual byte[] ComputeHash (byte[] input) {
  34. // inputData = input.Clone();
  35. HashCore (input, 0, input.Length);
  36. HashValue = HashFinal ();
  37. Initialize ();
  38. return HashValue;
  39. }
  40. /// <summary>
  41. /// Creates the default implementation of the default hash algorithm (SHA1).
  42. /// </summary>
  43. public static HashAlgorithm Create () {
  44. return SHA1.Create ();
  45. }
  46. /// <summary>
  47. /// Creates a specific implementation of the general hash idea.
  48. /// </summary>
  49. /// <param name="st">FIXME: No clue. Specifies which derived class to create.</param>
  50. [MonoTODO]
  51. public static HashAlgorithm Create (string st) {
  52. return Create ();
  53. }
  54. /// <summary>
  55. /// Gets the previously computed hash.
  56. /// </summary>
  57. public virtual byte[] Hash {
  58. get {
  59. return HashValue;
  60. }
  61. }
  62. /// <summary>
  63. /// When overridden in a derived class, drives the hashing function.
  64. /// </summary>
  65. /// <param name="rgb"></param>
  66. /// <param name="start"></param>
  67. /// <param name="size"></param>
  68. protected abstract void HashCore (byte[] rgb, int start, int size);
  69. /// <summary>
  70. /// When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created.
  71. /// </summary>
  72. protected abstract byte[] HashFinal ();
  73. /// <summary>
  74. /// Returns the size in bits of the hash.
  75. /// </summary>
  76. public virtual int HashSize {
  77. get {
  78. return HashSizeValue;
  79. }
  80. }
  81. /// <summary>
  82. /// When overridden in a derived class, initializes the object to prepare for hashing.
  83. /// </summary>
  84. public abstract void Initialize ();
  85. /// <summary>
  86. /// FIXME: Not quire valid for the hashes? Returns 1?
  87. /// </summary>
  88. [MonoTODO]
  89. public virtual int InputBlockSize {
  90. get {
  91. return 1;
  92. }
  93. }
  94. /// <summary>
  95. /// FIXME: Not quire valid for the hashes? Returns 1?
  96. /// </summary>
  97. [MonoTODO]
  98. public virtual int OutputBlockSize {
  99. get {
  100. return 1;
  101. }
  102. }
  103. /// <summary>
  104. /// Used for stream chaining. Computes hash as data passes through it.
  105. /// </summary>
  106. /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
  107. /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
  108. /// <param name="inputCount">The number of bytes to be copied.</param>
  109. /// <param name="outputBuffer">The buffer to write the copied data to.</param>
  110. /// <param name="outputOffset">At what point in the outputBuffer to write the data at.</param>
  111. public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) {
  112. Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
  113. HashCore (inputBuffer, inputOffset, inputCount);
  114. return inputCount;
  115. }
  116. /// <summary>
  117. /// Used for stream chaining. Computes hash as data passes through it. Finishes off the hash.
  118. /// </summary>
  119. /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
  120. /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
  121. /// <param name="inputCount">The number of bytes to be copied.</param>
  122. public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount) {
  123. byte[] outputBuffer = new byte[inputCount];
  124. Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, 0, inputCount);
  125. HashCore (inputBuffer, inputOffset, inputCount);
  126. HashValue = HashFinal ();
  127. Initialize ();
  128. return outputBuffer;
  129. }
  130. }
  131. }