Collection+Extension.swift 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. //
  2. // Collection+Extension.swift
  3. // CryptoSwift
  4. //
  5. // Created by Marcin Krzyzanowski on 02/08/16.
  6. // Copyright © 2016 Marcin Krzyzanowski. All rights reserved.
  7. //
  8. extension Collection where Self.Iterator.Element == UInt8, Self.Index == Int {
  9. func toUInt32Array() -> Array<UInt32> {
  10. var result = Array<UInt32>()
  11. result.reserveCapacity(16)
  12. for idx in stride(from: self.startIndex, to: self.endIndex, by: MemoryLayout<UInt32>.size) {
  13. var val: UInt32 = 0
  14. val |= self.count > 3 ? UInt32(self[idx.advanced(by: 3)]) << 24 : 0
  15. val |= self.count > 2 ? UInt32(self[idx.advanced(by: 2)]) << 16 : 0
  16. val |= self.count > 1 ? UInt32(self[idx.advanced(by: 1)]) << 8 : 0
  17. val |= self.count > 0 ? UInt32(self[idx]) : 0
  18. result.append(val)
  19. }
  20. for _ in result.count..<MemoryLayout<UInt32>.size {
  21. result.append(0)
  22. }
  23. return result
  24. }
  25. func toUInt64Array() -> Array<UInt64> {
  26. var result = Array<UInt64>()
  27. result.reserveCapacity(32)
  28. for idx in stride(from: self.startIndex, to: self.endIndex, by: MemoryLayout<UInt64>.size) {
  29. var val:UInt64 = 0
  30. val |= self.count > 7 ? UInt64(self[idx.advanced(by: 7)]) << 56 : 0
  31. val |= self.count > 6 ? UInt64(self[idx.advanced(by: 6)]) << 48 : 0
  32. val |= self.count > 5 ? UInt64(self[idx.advanced(by: 5)]) << 40 : 0
  33. val |= self.count > 4 ? UInt64(self[idx.advanced(by: 4)]) << 32 : 0
  34. val |= self.count > 3 ? UInt64(self[idx.advanced(by: 3)]) << 24 : 0
  35. val |= self.count > 2 ? UInt64(self[idx.advanced(by: 2)]) << 16 : 0
  36. val |= self.count > 1 ? UInt64(self[idx.advanced(by: 1)]) << 8 : 0
  37. val |= self.count > 0 ? UInt64(self[idx.advanced(by: 0)]) << 0 : 0
  38. result.append(val)
  39. }
  40. for _ in result.count..<MemoryLayout<UInt64>.size {
  41. result.append(0)
  42. }
  43. return result
  44. }
  45. /// Initialize integer from array of bytes. Caution: may be slow!
  46. func toInteger<T:Integer>() -> T where T: ByteConvertible, T: BitshiftOperationsType {
  47. if self.count == 0 {
  48. return 0;
  49. }
  50. var bytes = self.reversed() //FIXME: check it this is equivalent of Array(...)
  51. if bytes.count < MemoryLayout<T>.size {
  52. let paddingCount = MemoryLayout<T>.size - bytes.count
  53. if (paddingCount > 0) {
  54. bytes += Array<UInt8>(repeating: 0, count: paddingCount)
  55. }
  56. }
  57. if MemoryLayout<T>.size == 1 {
  58. return T(truncatingBitPattern: UInt64(bytes[0]))
  59. }
  60. var result: T = 0
  61. for byte in bytes.reversed() {
  62. result = result << 8 | T(byte)
  63. }
  64. return result
  65. }
  66. }