HashAlgorithm.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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. public virtual bool CanTransformMultipleBlocks {
  25. get {
  26. return true;
  27. }
  28. }
  29. /// <summary>
  30. /// Computes the entire hash of all the bytes in the byte array.
  31. /// </summary>
  32. public virtual byte[] ComputeHash (byte[] input) {
  33. // inputData = input.Clone();
  34. HashCore (input, 0, input.Length);
  35. HashValue = HashFinal ();
  36. Initialize ();
  37. return HashValue;
  38. }
  39. /// <summary>
  40. /// Creates the default implementation of the default hash algorithm (SHA1).
  41. /// </summary>
  42. public static HashAlgorithm Create () {
  43. return SHA1.Create ();
  44. }
  45. /// <summary>
  46. /// Creates a specific implementation of the general hash idea.
  47. /// </summary>
  48. /// <param name="st">FIXME: No clue. Specifies which derived class to create.</param>
  49. public static HashAlgorithm Create (string st) {
  50. return Create ();
  51. }
  52. /// <summary>
  53. /// Gets the previously computed hash.
  54. /// </summary>
  55. public virtual byte[] Hash {
  56. get {
  57. return HashValue;
  58. }
  59. }
  60. /// <summary>
  61. /// When overridden in a derived class, drives the hashing function.
  62. /// </summary>
  63. /// <param name="rgb"></param>
  64. /// <param name="start"></param>
  65. /// <param name="size"></param>
  66. protected abstract void HashCore (byte[] rgb, int start, int size);
  67. /// <summary>
  68. /// When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created.
  69. /// </summary>
  70. protected abstract byte[] HashFinal ();
  71. /// <summary>
  72. /// Returns the size in bits of the hash.
  73. /// </summary>
  74. public virtual int HashSize {
  75. get {
  76. return HashSizeValue;
  77. }
  78. }
  79. /// <summary>
  80. /// When overridden in a derived class, initializes the object to prepare for hashing.
  81. /// </summary>
  82. public abstract void Initialize ();
  83. /// <summary>
  84. /// FIXME: Not quire valid for the hashes? Returns 1?
  85. /// </summary>
  86. public virtual int InputBlockSize {
  87. get {
  88. return 1;
  89. }
  90. }
  91. /// <summary>
  92. /// FIXME: Not quire valid for the hashes? Returns 1?
  93. /// </summary>
  94. public virtual int OutputBlockSize {
  95. get {
  96. return 1;
  97. }
  98. }
  99. /// <summary>
  100. /// Used for stream chaining. Computes hash as data passes through it.
  101. /// </summary>
  102. /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
  103. /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
  104. /// <param name="inputCount">The number of bytes to be copied.</param>
  105. /// <param name="outputBuffer">The buffer to write the copied data to.</param>
  106. /// <param name="outputOffset">At what point in the outputBuffer to write the data at.</param>
  107. public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) {
  108. Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
  109. HashCore (inputBuffer, inputOffset, inputCount);
  110. return inputCount;
  111. }
  112. /// <summary>
  113. /// Used for stream chaining. Computes hash as data passes through it. Finishes off the hash.
  114. /// </summary>
  115. /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
  116. /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
  117. /// <param name="inputCount">The number of bytes to be copied.</param>
  118. public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount) {
  119. byte[] outputBuffer = new byte[inputCount];
  120. Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, 0, inputCount);
  121. HashCore (inputBuffer, inputOffset, inputCount);
  122. HashValue = HashFinal ();
  123. Initialize ();
  124. return outputBuffer;
  125. }
  126. }
  127. }