我正在尝试移植用于计算OpenSubtitles哈希的代码,并且我使用Objective-C示例作为参考(http://trac.opensubtitles.org/projects/opensubtitles/wiki/HashSourceCodes#Objective-C)。哈希的公式是文件大小+文件的前64k的64位校验和+文件的最后64k的64位校验和。
我在计算校验和的代码中遇到了麻烦。这是Objective-C中代码的重要部分:
const NSUInteger CHUNK_SIZE=65536;
NSData *fileDataBegin, *fileDataEnd;
uint64_t hash=0;
fileDataBegin = [handle readDataOfLength:(NSUInteger)CHUNK_SIZE];
[handle seekToEndOfFile];
unsigned long long fileSize = [handle offsetInFile];
uint64_t * data_bytes= (uint64_t*)[fileDataBegin bytes];
for( int i=0; i< CHUNK_SIZE/sizeof(uint64_t); i++ )
hash+=data_bytes[i];
我尝试通过以类似方式重写代码来转换大部分代码ti Swift。我在为这一点找到替换代码时遇到了麻烦:
uint64_t * data_bytes= (uint64_t*)[fileDataBegin bytes];
for( int i=0; i< CHUNK_SIZE/sizeof(uint64_t); i++ )
hash+=data_bytes[i];
任何帮助都会很棒。
答案 0 :(得分:1)
uint64_t * data_bytes= (uint64_t*)[fileDataBegin bytes];
可翻译为
let data_bytes = UnsafeBufferPointer<UInt64>(
start: UnsafePointer(fileDataBegin.bytes),
count: fileDataBegin.length/sizeof(UInt64)
)
具有data_bytes
不仅仅具有额外优势
一个指针,但也存储元素的数量。一个
UnsafeBufferPointer
几乎可以像Swift Array
一样对待。
因此
for( int i=0; i< CHUNK_SIZE/sizeof(uint64_t); i++ )
hash+=data_bytes[i];
可以简单地写成
var hash : UInt64 = 0
// ...
hash = reduce(data_bytes, hash) { $0 &+ $1 }
使用
/// Return the result of repeatedly calling `combine` with an
/// accumulated value initialized to `initial` and each element of
/// `sequence`, in turn.
func reduce<S : SequenceType, U>(sequence: S, initial: U, combine: (U, S.Generator.Element) -> U) -> U
和"overflow operator" &+
:
与C中的算术运算符不同,Swift中的算术运算符不相同 默认溢出。溢出行为被捕获并报告为 错误。要选择溢出行为,请使用Swift的第二组 默认情况下溢出的算术运算符,例如溢出 加法运算符(&amp; +)。所有这些溢出运算符都以a开头 &符号(&amp;)。