UInt32Extension.swift 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. #if os(Linux)
  9. import Glibc
  10. #else
  11. import Darwin
  12. #endif
  13. protocol _UInt32Type { }
  14. extension UInt32: _UInt32Type {}
  15. /** array of bytes */
  16. extension UInt32 {
  17. public func bytes(totalBytes: Int = sizeof(UInt32)) -> [UInt8] {
  18. return arrayOfBytes(self, length: totalBytes)
  19. }
  20. public static func withBytes(bytes: ArraySlice<UInt8>) -> UInt32 {
  21. return UInt32.withBytes(Array(bytes))
  22. }
  23. /** Int with array bytes (little-endian) */
  24. public static func withBytes(bytes: [UInt8]) -> UInt32 {
  25. return integerWithBytes(bytes)
  26. }
  27. }
  28. /** Shift bits */
  29. extension UInt32 {
  30. /** Shift bits to the left. All bits are shifted (including sign bit) */
  31. private mutating func shiftLeft(count: UInt32) -> UInt32 {
  32. if (self == 0) {
  33. return self;
  34. }
  35. let bitsCount = UInt32(sizeof(UInt32) * 8)
  36. let shiftCount = Swift.min(count, bitsCount - 1)
  37. var shiftedValue:UInt32 = 0;
  38. for bitIdx in 0..<bitsCount {
  39. // if bit is set then copy to result and shift left 1
  40. let bit = 1 << bitIdx
  41. if ((self & bit) == bit) {
  42. shiftedValue = shiftedValue | (bit << shiftCount)
  43. }
  44. }
  45. if (shiftedValue != 0 && count >= bitsCount) {
  46. // clear last bit that couldn't be shifted out of range
  47. shiftedValue = shiftedValue & (~(1 << (bitsCount - 1)))
  48. }
  49. self = shiftedValue
  50. return self
  51. }
  52. /** Shift bits to the right. All bits are shifted (including sign bit) */
  53. private mutating func shiftRight(count: UInt32) -> UInt32 {
  54. if (self == 0) {
  55. return self;
  56. }
  57. let bitsCount = UInt32(sizeofValue(self) * 8)
  58. if (count >= bitsCount) {
  59. return 0
  60. }
  61. let maxBitsForValue = UInt32(floor(log2(Double(self)) + 1))
  62. let shiftCount = Swift.min(count, maxBitsForValue - 1)
  63. var shiftedValue:UInt32 = 0;
  64. for bitIdx in 0..<bitsCount {
  65. // if bit is set then copy to result and shift left 1
  66. let bit = 1 << bitIdx
  67. if ((self & bit) == bit) {
  68. shiftedValue = shiftedValue | (bit >> shiftCount)
  69. }
  70. }
  71. self = shiftedValue
  72. return self
  73. }
  74. }
  75. /** shift left and assign with bits truncation */
  76. public func &<<= (inout lhs: UInt32, rhs: UInt32) {
  77. lhs.shiftLeft(rhs)
  78. }
  79. /** shift left with bits truncation */
  80. public func &<< (lhs: UInt32, rhs: UInt32) -> UInt32 {
  81. var l = lhs;
  82. l.shiftLeft(rhs)
  83. return l
  84. }
  85. /** shift right and assign with bits truncation */
  86. func &>>= (inout lhs: UInt32, rhs: UInt32) {
  87. lhs.shiftRight(rhs)
  88. }
  89. /** shift right and assign with bits truncation */
  90. func &>> (lhs: UInt32, rhs: UInt32) -> UInt32 {
  91. var l = lhs;
  92. l.shiftRight(rhs)
  93. return l
  94. }