【发布时间】:2015-02-09 08:44:28
【问题描述】:
我一直在尝试将 Rc4 算法从 Objective-c 重写为 swift,以测试 apples(现已旧)声称它运行得更快。 但是,在这些时候,我一定是在某个地方做错了什么
这是目标c代码:
+(NSString*)Rc4:(NSString*)aInput key:(NSString *)aKey {
NSMutableArray *iS = [[NSMutableArray alloc] initWithCapacity:256];
NSMutableArray *iK = [[NSMutableArray alloc] initWithCapacity:256];
for (int i = 0; i <256;i++){
[iS addObject:[NSNumber numberWithInt:i]];
}
for(short i=0;i<256;i++){
UniChar c = [aKey characterAtIndex:i%aKey.length];
[iK addObject:[NSNumber numberWithChar:c]];
}
int j=2;
for (int i=0; i<255;i++){
int is = [[iS objectAtIndex:i] intValue];
UniChar ik = (UniChar)[[iK objectAtIndex:i]charValue];
j= (j+is+ik)%256;
NSNumber *temp = [iS objectAtIndex:i];
[iS replaceObjectAtIndex:i withObject:[iS objectAtIndex:j]];
[iS replaceObjectAtIndex:j withObject:temp];
}
int i =0;
j=0;
NSString *result = aInput;
for (short x=0;x<[aInput length]; x++){
i = (i+1)%256;
int is = [[iS objectAtIndex:i]intValue];
j=(j+is)%256;
int is_i = [[iS objectAtIndex:i]intValue];
int is_j = [[iS objectAtIndex:j]intValue];
int t= (is_i+is_j)%256;
int iY = [[iS objectAtIndex:t]intValue];
UniChar ch = (UniChar)[aInput characterAtIndex:x];
UniChar ch_y=ch^iY;
//NSLog(ch);
//NSLog(iY);
result = [result stringByReplacingCharactersInRange:NSMakeRange(x,1) withString:
[NSString stringWithCharacters:&ch_y length:1] ];
}
[iS release];
[iK release];
return result;
}
使用 -O3 编译时运行速度非常快,我得到了以下时间:
100 次运行:0.006 秒
带密钥:6f7e2a3d744a3b5859725f412f (128bit)
并输入:“MySecretCodeToBeEncryptionSoNobodySeesIt”
这是我尝试使用 Swift 以同样的方式实现它:
extension String {
subscript (i: Int) -> String {
return String(Array(self)[i])
}
}
extension Character {
func unicodeValue() -> UInt32 {
for s in String(self).unicodeScalars {
return s.value
}
return 0
}
}
func Rc4(input:String, key:String)-> String{
var iS = Array(count:256, repeatedValue: 0)
var iK = Array(count:256, repeatedValue: "")
var keyLength = countElements(key)
for var i = 0; i < 256; i++ {
iS[i] = i;
}
for var i = 0; i < 256 ; i++ {
var c = key[i%keyLength]
iK[i] = c;
}
var j = 2
for var i = 0; i < 255; i++ {
var iss = iS[i]
var ik = iK[i]
// transform string to int
var ik_x:Character = Character(ik)
var ikk_xx = Int(ik_x.unicodeValue())
j = (j+iss+ikk_xx)%256;
var temp = iS[i]
iS[i] = iS[j]
iS[j] = temp
}
var i = 0
j=0
var result = input
var eles = countElements(input)
for var x = 0 ; x<eles ; x++ {
i = (i+1)%256
var iss = iS[i]
j = (j+iss)%256
var is_i = iS[i]
var is_j = iS[j]
var t = (is_i+is_j)%256
var iY = iS[t]
var ch = (input[x])
var ch_x:Character = Character(ch)
var ch_xx = Int(ch_x.unicodeValue())
var ch_y = ch_xx^iY
var start = advance(result.startIndex, x)
var end = advance(start,1);
let range = Range(start:start, end:end)
var maybestring = String(UnicodeScalar(ch_y))
result = result.stringByReplacingCharactersInRange(range, withString:maybestring)
}
return result;
}
我已经尝试实现它,使它看起来尽可能像objective-c 版本。 然而,这给了我这些可怕的时刻,使用 -O
100 次运行:0.5 秒
编辑 代码现在应该使用我发布的扩展方法在 xcode 6.1 中运行。
我像这样从终端运行它:
xcrun swiftc -O Swift.swift -o swift
Swift.swift 是我的文件,swift 是我的可执行文件
【问题讨论】:
-
您的 Swift 代码未在 Xcode 6.1 中构建。
-
在任何一种情况下都不要在实际加密部分中使用字符串。加密是一种数据操作。将您的结果与 Common Crypto 进行比较,您应该会发现这两种实现都不是很接近。
-
这里的目的是在 Objective-c 和 swift 中测试非常相似的代码片段,我以为我正在这样做,但是这些奇怪的运行时正在反对它。这与优化加密的安全性甚至是正确的无关。不过,感谢您的输入,如果看起来很奇怪,请见谅。
-
Swift 中的字符串可能非常慢,因为由于更好的 unicode 处理,没有直接索引到它们。添加到 String 的扩展不是一个好主意,它们不适用于需要多个 UTF-16 代码单元的 unicode 字符,例如表情符号,这就是为什么它们不是 Swift 的一部分。由于扩展不适用于所有字符串字符,因此只需将方法设为私有即可。还要检查 Swift 编译优化级别。
-
我实际上一直在寻找有关编译优化级别的文档 (stackoverflow.com/questions/27233479/…) 据我所知 -O (swift) 类似于 -O3 (objective-c) 但我没有能够找到任何严格的文档来支持这一点。再次感谢!
标签: objective-c swift performance encryption microbenchmark