FourByteSixByteEncoding.swift 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. //
  2. // FourByteSixByteEncoding.swift
  3. // RileyLink
  4. //
  5. // Created by Pete Schwamb on 2/27/16.
  6. // Copyright © 2016 Pete Schwamb. All rights reserved.
  7. //
  8. import Foundation
  9. fileprivate let codes = [21, 49, 50, 35, 52, 37, 38, 22, 26, 25, 42, 11, 44, 13, 14, 28]
  10. fileprivate let codesRev = Dictionary<Int, UInt8>(uniqueKeysWithValues: codes.enumerated().map({ ($1, UInt8($0)) }))
  11. public extension Sequence where Element == UInt8 {
  12. func decode4b6b() -> [UInt8]? {
  13. var buffer = [UInt8]()
  14. var availBits = 0
  15. var bitAccumulator = 0
  16. for byte in self {
  17. if byte == 0 {
  18. break
  19. }
  20. bitAccumulator = (bitAccumulator << 8) + Int(byte)
  21. availBits += 8
  22. if availBits >= 12 {
  23. guard let hiNibble = codesRev[bitAccumulator >> (availBits - 6)],
  24. let loNibble = codesRev[(bitAccumulator >> (availBits - 12)) & 0b111111]
  25. else {
  26. return nil
  27. }
  28. let decoded = UInt8((hiNibble << 4) + loNibble)
  29. buffer.append(decoded)
  30. availBits -= 12
  31. bitAccumulator = bitAccumulator & (0xffff >> (16-availBits))
  32. }
  33. }
  34. return buffer
  35. }
  36. func encode4b6b() -> [UInt8] {
  37. var buffer = [UInt8]()
  38. var bitAccumulator = 0x0
  39. var bitcount = 0
  40. for byte in self {
  41. bitAccumulator <<= 6
  42. bitAccumulator |= codes[Int(byte >> 4)]
  43. bitcount += 6
  44. bitAccumulator <<= 6
  45. bitAccumulator |= codes[Int(byte & 0x0f)]
  46. bitcount += 6
  47. while bitcount >= 8 {
  48. buffer.append(UInt8(bitAccumulator >> (bitcount-8)) & 0xff)
  49. bitcount -= 8
  50. bitAccumulator &= (0xffff >> (16-bitcount))
  51. }
  52. }
  53. if bitcount > 0 {
  54. bitAccumulator <<= (8-bitcount)
  55. buffer.append(UInt8(bitAccumulator) & 0xff)
  56. }
  57. return buffer
  58. }
  59. }