UInt32Extension.swift 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //
  2. // UInt32Extension.swift
  3. // CryptoSwift
  4. //
  5. // Created by Marcin Krzyzanowski on 02/09/14.
  6. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
  7. //
  8. import Foundation
  9. /** array of bytes */
  10. extension UInt32 {
  11. public func bytes(_ totalBytes: Int = sizeof(UInt32)) -> [Byte] {
  12. return arrayOfBytes(self, length: totalBytes)
  13. }
  14. public static func withBytes(bytes: Slice<Byte>) -> UInt32 {
  15. return UInt32.withBytes(Array(bytes))
  16. }
  17. /** Int with array bytes (little-endian) */
  18. public static func withBytes(bytes: [Byte]) -> UInt32 {
  19. return integerWithBytes(bytes)
  20. }
  21. }
  22. /** Shift bits */
  23. extension UInt32 {
  24. /** Shift bits to the left. All bits are shifted (including sign bit) */
  25. private mutating func shiftLeft(count: UInt32) -> UInt32 {
  26. if (self == 0) {
  27. return self;
  28. }
  29. var bitsCount = UInt32(sizeof(UInt32) * 8)
  30. var shiftCount = Swift.min(count, bitsCount - 1)
  31. var shiftedValue:UInt32 = 0;
  32. for bitIdx in 0..<bitsCount {
  33. // if bit is set then copy to result and shift left 1
  34. var bit = 1 << bitIdx
  35. if ((self & bit) == bit) {
  36. shiftedValue = shiftedValue | (bit << shiftCount)
  37. }
  38. }
  39. if (shiftedValue != 0 && count >= bitsCount) {
  40. // clear last bit that couldn't be shifted out of range
  41. shiftedValue = shiftedValue & (~(1 << (bitsCount - 1)))
  42. }
  43. self = shiftedValue
  44. return self
  45. }
  46. /** Shift bits to the right. All bits are shifted (including sign bit) */
  47. private mutating func shiftRight(count: UInt32) -> UInt32 {
  48. if (self == 0) {
  49. return self;
  50. }
  51. var bitsCount = UInt32(sizeofValue(self) * 8)
  52. if (count >= bitsCount) {
  53. return 0
  54. }
  55. var maxBitsForValue = UInt32(floor(log2(Double(self)) + 1))
  56. var shiftCount = Swift.min(count, maxBitsForValue - 1)
  57. var shiftedValue:UInt32 = 0;
  58. for bitIdx in 0..<bitsCount {
  59. // if bit is set then copy to result and shift left 1
  60. var bit = 1 << bitIdx
  61. if ((self & bit) == bit) {
  62. shiftedValue = shiftedValue | (bit >> shiftCount)
  63. }
  64. }
  65. self = shiftedValue
  66. return self
  67. }
  68. }
  69. /** shift left and assign with bits truncation */
  70. public func &<<= (inout lhs: UInt32, rhs: UInt32) {
  71. lhs.shiftLeft(rhs)
  72. }
  73. /** shift left with bits truncation */
  74. public func &<< (lhs: UInt32, rhs: UInt32) -> UInt32 {
  75. var l = lhs;
  76. l.shiftLeft(rhs)
  77. return l
  78. }
  79. /** shift right and assign with bits truncation */
  80. func &>>= (inout lhs: UInt32, rhs: UInt32) {
  81. lhs.shiftRight(rhs)
  82. }
  83. /** shift right and assign with bits truncation */
  84. func &>> (lhs: UInt32, rhs: UInt32) -> UInt32 {
  85. var l = lhs;
  86. l.shiftRight(rhs)
  87. return l
  88. }