GVKun编程网logo

如何在Swift中使用SHA1哈希NSString?(swift hashable)

19

本文将介绍如何在Swift中使用SHA1哈希NSString?的详细情况,特别是关于swifthashable的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉

本文将介绍如何在Swift中使用SHA1哈希NSString?的详细情况,特别是关于swift hashable的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于ios – 如何在Swift 4中使用Swift 3的已废弃语法、ios – 如何在SWIFT中使用SpriteKit脉冲精灵、iOS – 如何在swift中使用`NSMutableString`、ios – 如何在Swift中的NSData和NSString表示之间转换推送令牌?的知识。

本文目录一览:

如何在Swift中使用SHA1哈希NSString?(swift hashable)

如何在Swift中使用SHA1哈希NSString?(swift hashable)

在Objective-C中,它看起来像这样:

#include <sys/xattr.h>@implementation NSString (reverse)-(NSString*)sha1{    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];    uint8_t digest[CC_SHA1_DIGEST_LENGTH];    CC_SHA1(data.bytes, (int)data.length, digest);    NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];    for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)        [output appendFormat:@"%02x", digest[i]];    return output;}@end

我需要Swift这样的东西,可以吗?

请显示工作示例。

答案1

小编典典

您的Objective-C代码(使用NSString类别)可以直接转换为Swift(使用String扩展名)。

首先,您必须创建一个“桥接头”并添加

#import <CommonCrypto/CommonCrypto.h>

然后:

extension String {    func sha1() -> String {        let data = self.dataUsingEncoding(NSUTF8StringEncoding)!        var digest = [UInt8](count:Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0)        CC_SHA1(data.bytes, CC_LONG(data.length), &digest)        let output = NSMutableString(capacity: Int(CC_SHA1_DIGEST_LENGTH))        for byte in digest {            output.appendFormat("%02x", byte)        }        return output as String    }}println("Hello World".sha1())

这可以写得更短和更快速

extension String {    func sha1() -> String {        let data = self.dataUsingEncoding(NSUTF8StringEncoding)!        var digest = [UInt8](count:Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0)        CC_SHA1(data.bytes, CC_LONG(data.length), &digest)        let hexBytes = map(digest) { String(format: "%02hhx", $0) }        return "".join(hexBytes)    }}

Swift 2更新:

extension String {    func sha1() -> String {        let data = self.dataUsingEncoding(NSUTF8StringEncoding)!        var digest = [UInt8](count:Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0)        CC_SHA1(data.bytes, CC_LONG(data.length), &digest)        let hexBytes = digest.map { String(format: "%02hhx", $0) }        return hexBytes.joinWithSeparator("")    }}

要返回以Base-64编码的字符串而不是十六进制编码的字符串,只需替换

        let hexBytes = digest.map { String(format: "%02hhx", $0) }        return hexBytes.joinWithSeparator("")

        return NSData(bytes: digest, length: digest.count).base64EncodedStringWithOptions([])

Swift 3更新:

extension String {    func sha1() -> String {        let data = self.data(using: String.Encoding.utf8)!        var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))        data.withUnsafeBytes {             _ = CC_SHA1($0, CC_LONG(data.count), &digest)        }        let hexBytes = digest.map { String(format: "%02hhx", $0) }        return hexBytes.joined()    }}

要返回以Base-64编码的字符串而不是十六进制编码的字符串,只需替换

        let hexBytes = digest.map { String(format: "%02hhx", $0) }        return hexBytes.joined()

通过

        return Data(bytes: digest).base64EncodedString()

Swift 4更新:

不再需要桥接头文件,import CommonCrypto而可以:

import CommonCryptoextension String {    func sha1() -> String {        let data = Data(self.utf8)        var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))        data.withUnsafeBytes {             _ = CC_SHA1($0, CC_LONG(data.count), &digest)        }        let hexBytes = digest.map { String(format: "%02hhx", $0) }        return hexBytes.joined()    }}

Swift 5更新:

Data.withUnsafeBytes()方法现在使用to
调用闭包UnsafeRawBufferPointer,并baseAddress用于将初始地址传递给C函数:

import CommonCryptoextension String {    func sha1() -> String {        let data = Data(self.utf8)        var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))        data.withUnsafeBytes {             _ = CC_SHA1($0.baseAddress, CC_LONG(data.count), &digest)        }        let hexBytes = digest.map { String(format: "%02hhx", $0) }        return hexBytes.joined()    }}

ios – 如何在Swift 4中使用Swift 3的已废弃语法

ios – 如何在Swift 4中使用Swift 3的已废弃语法

录制视频,同时设置视频编解码器如下:

sessionOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecTypeJPEG]

XCode称’AVVideoCodecTypeJPEG’已重命名为’AVVideoCodecType.jpeg’,’AVVideoCodecTypeJPEG’已在Swift 3中废弃,它建议将’AVVideoCodecTypeJPEG’替换为’AVVideoCodecType.jpeg’

在这之后,XCode说’jpeg’仅适用于iOS 11.0或更高版本.

问题是我必须使用iOS 10并且想要使用Swift 4.

有没有任何解决方案可以在iOS 10的Swift 4中使用这样的功能?

解决方法

我认为解决此类问题的正确方法是使用新的AVVideoCodecType.jpeg和弃用的AVVideoCodecJPEG,这样做:

if #available(iOS 11.0,*) {
    sessionOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecType.jpeg]
} else {
    sessionOutput.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG]
}

ios – 如何在SWIFT中使用SpriteKit脉冲精灵

ios – 如何在SWIFT中使用SpriteKit脉冲精灵

我试图在SK / SWIFT中“脉冲”一个精灵.我尝试使用For循环和.setScale是粗略的,但它们没有工作(没有错误 – 只是没有动画).我觉得使用SKActions可能会更优雅.

在使用下面的帮助后,这是我目前的实施.但是,它出现了编译错误;

Expected member name or constructor call after type name &
Consecutive statement on a line must be separated by a ;

这是我正在使用的代码:

SKAction *pulseUp = [SKAction.scaleto(3.0,duration: 3.0)]
SKAction *pulseDown = [SKAction.scaleto(1.0,duration: 3.0)]
SKAction *pulse = [SKAction.sequence(pulseUp,pulseDown)]
SKAction *repeat = [SKAction repeatActionForever:pulse]]
[self.playButton runAction: repeat]

任何帮助将不胜感激.

解决方法

在带有Swift的xCode版本8.3.3中,

let pulseUp = SKAction.scale(to: 3.0,duration: 1.0)
    let pulseDown = SKAction.scale(to: 0.5,duration: 1.0)
    let pulse = SKAction.sequence([pulseUp,pulseDown])
    let repeatpulse = SKAction.repeatForever(pulse)
    self.playButton.run(repeatpulse)

iOS – 如何在swift中使用`NSMutableString`

iOS – 如何在swift中使用`NSMutableString`

我已经看过这个Objective-C代码,但我很难在 swift中做同样的事情:

NSMutableAttributedString *res = [self.richTextEditor.attributedText mutablecopy];

[res beginEditing];
__block BOOL found = NO;
[res enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0,res.length) options:0 usingBlock:^(id value,NSRange range,BOOL *stop) {
    if (value) {
        UIFont *oldFont = (UIFont *)value;
        UIFont *newFont = [oldFont fontWithSize:oldFont.pointSize * 2];
        [res removeAttribute:NSFontAttributeName range:range];
        [res addAttribute:NSFontAttributeName value:newFont range:range];
        found = YES;
    }
}];
if (!found) {
    // No font was found - do something else?
}
[res endEditing];
self.richTextEditor.attributedText = res;

我试图通过迭代每个属性来更改NSMutableAttributedString中的字体.我很高兴听到有更好的方法,但如果有人能帮助我翻译上述内容,我会感到非常满意.

解决方法

这是一个基本的实现.这对我来说似乎很简单,你没有提供你的尝试,所以我不确定你是否有类似的东西,它有问题,或者如果你刚刚接触Swift.

一个区别是这个实现使用可选的转换(如?),我这样做是为了演示这个概念.实际上,这不需要是可选的,因为NSFontAttributeName保证提供UIFont.

var res : NSMutableAttributedString = NSMutableAttributedString(string: "test");

res.beginEditing()

var found = false

res.enumerateAttribute(NSFontAttributeName,inRange: NSMakeRange(0,res.length),options: NSAttributedStringEnumerationoptions(0)) { (value,range,stop) -> Void in
    if let oldFont = value as? UIFont {
        let newFont = oldFont.fontWithSize(oldFont.pointSize * 2)
        res.removeAttribute(NSFontAttributeName,range: range)
        res.addAttribute(NSFontAttributeName,value: newFont,range: range)
        found = true
    }
}

if found == false {

}

res.endEditing()

ios – 如何在Swift中的NSData和NSString表示之间转换推送令牌?

ios – 如何在Swift中的NSData和NSString表示之间转换推送令牌?

我已经使用了以下Objective C例程多年,将NSData推送令牌转换为Nsstring(供Web侧推送服务使用),反之,获取令牌的已知Nsstring版本并重新创建NSData表示.现在,我发现需要完全相同的功能,但在 Swift中.

dataToHex Objective C代码主要使用printf格式:

- (Nsstring *)dataToHex:(NSData *)data
{
    NSMutableString *str = [NSMutableString stringWithCapacity:100];
    const unsigned char *p = [data bytes];
    NSUInteger len = [data length];
    for(int i=0; i<len; ++i) {
      [str appendFormat:@"%02.2X",p[i]];
    }
    return str; 
}

逆向翻译是:

- (NSData *)hexToData:(Nsstring *)str 
{
    const char *ptr = [str cStringUsingEncoding:NSASCIIStringEncoding];
    NSUInteger len = [str length]/2;
    NSMutableData *data = [NSMutableData dataWithCapacity:len];
    while(len--) {
        char num[5] = (char[]){ '0','x',0 };
        num[2] = *ptr++;
        num[3] = *ptr++;
        uint8_t n = (uint8_t)strtol(num,NULL,0);

        [data appendBytes:&n length:1];
    }
    return data;
}

通过“巧妙地”覆盖ASCII数组中的两个字节,“0xXX”字符串将转换为一个字节,然后将其附加到可变数据对象.

既然我在Swift编码,我需要相同的功能,但没有发现任何类似Swift上面代码的帖子.

解决方法

从iOS提供的NSData表示转换匹配Objective C代码几乎为line:

func dataToHex(data: NSData) -> String
{
    var str: String = String()
    let p = UnsafePointer<UInt8>(data.bytes)
    let len = data.length

    for var i=0; i<len; ++i {
        str += String(format: "%02.2X",p[i])
    }
    return str
}

但是,给定一个Nsstring对象,转换回NSData对象有点困难.如果您在模拟器中进行测试,从真实设备获得字符串标记,并且需要它来注册服务,则可能需要执行此操作.

我采用的第一种方法试图复制我之前使用的代码,通过创建一个包含字符对的字符串,并调用strtol:

func hexToData0(str: Nsstring) -> NSData {
    let len = str.length/2
    var data = NSMutableData(capacity:len)!
    var num: [Int8] = [ 0,0 ]
    let ptr = str.cStringUsingEncoding(NSUTF8StringEncoding)

    for var i=0; i<len; ++i {
        num[0] = ptr[i*2+0]
        num[1] = ptr[i*2+1]
        var n = UInt8 ( strtol(&num,nil,16) )

        data.appendBytes(&n,length:1)
    }
    return data;
}

我只觉得strtol有点像黑客,所以我使用NSScanner做了同样的代码大小相同,但效率最低:

func hexToData1(str: Nsstring) -> NSData {
    var data = NSMutableData(capacity: str.length/2)!
    for var i = 0; i<str.length; i+=2 {
        let r = NSRange(location: i,length: 2)
        let s = str.substringWithRange(r)
        let sc = NSScanner(string: s)

        var val: UInt32 = 0
        let ret = sc.scanHexInt(&val)
        if ret {
            var b = UInt8(val)
            data.appendBytes(&b,length: 1)
        } else {
            assert(false,"Yikes!")
        }
    }
    return data
}

然后,我想到我可以在Swift中完成所有工作,不需要达尔文或基金会,而代价是更多的代码:

// Swift 4
func hexToData(str: String) -> Data {
    let len = str.count/2
    var data = Data(capacity:len)
    let ptr = str.cString(using: String.Encoding.utf8)!

    for i in 0..<len {
        var num: UInt8 = 0
        var multi: UInt8 = 16;
        for j in 0..<2 {
            let c: UInt8 = UInt8(ptr[i*2+j])
            var offset: UInt8 = 0

            switch c {
            case 48...57:   // '0'-'9'
                offset = 48
            case 65...70:   // 'A'-'F'
                offset = 65 - 10         // 10 since 'A' is 10,not 0
            case 97...102:  // 'a'-'f'
                offset = 97 - 10         // 10 since 'a' is 10,not 0
            default:
                assert(false)
            }

            num += (c - offset)*multi
            multi = 1
        }
        data.append(num)
    }
    return data;
}

我在我的代码中使用了最终的hexToData.

今天的关于如何在Swift中使用SHA1哈希NSString?swift hashable的分享已经结束,谢谢您的关注,如果想了解更多关于ios – 如何在Swift 4中使用Swift 3的已废弃语法、ios – 如何在SWIFT中使用SpriteKit脉冲精灵、iOS – 如何在swift中使用`NSMutableString`、ios – 如何在Swift中的NSData和NSString表示之间转换推送令牌?的相关知识,请在本站进行查询。

本文标签: