45 lines
1.5 KiB
Swift
Executable File
45 lines
1.5 KiB
Swift
Executable File
import Foundation
|
|
|
|
open class Checksum {
|
|
|
|
public static func computeChecksum(_ data: Data, from start: Int = 0, to end: Int? = nil, withPseudoHeaderChecksum initChecksum: UInt32 = 0) -> UInt16 {
|
|
return toChecksum(computeChecksumUnfold(data, from: start, to: end, withPseudoHeaderChecksum: initChecksum))
|
|
}
|
|
|
|
public static func validateChecksum(_ payload: Data, from start: Int = 0, to end: Int? = nil) -> Bool {
|
|
let cs = computeChecksumUnfold(payload, from: start, to: end)
|
|
return toChecksum(cs) == 0
|
|
}
|
|
|
|
public static func computeChecksumUnfold(_ data: Data, from start: Int = 0, to end: Int? = nil, withPseudoHeaderChecksum initChecksum: UInt32 = 0) -> UInt32 {
|
|
let scanner = BinaryDataScanner(data: data, littleEndian: true)
|
|
scanner.skip(to: start)
|
|
var result: UInt32 = initChecksum
|
|
var end = end
|
|
if end == nil {
|
|
end = data.count
|
|
}
|
|
while scanner.position + 2 <= end! {
|
|
let value = scanner.read16()!
|
|
result += UInt32(value)
|
|
}
|
|
|
|
if scanner.position != end {
|
|
// data is of odd size
|
|
// Intel and ARM are both litten endian
|
|
// so just add it
|
|
let value = scanner.readByte()!
|
|
result += UInt32(value)
|
|
}
|
|
return result
|
|
}
|
|
|
|
public static func toChecksum(_ checksum: UInt32) -> UInt16 {
|
|
var result = checksum
|
|
while (result) >> 16 != 0 {
|
|
result = result >> 16 + result & 0xFFFF
|
|
}
|
|
return ~UInt16(result)
|
|
}
|
|
}
|