Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 864 Vote(s) - 3.5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to hash NSString with SHA1 in Swift?

#1
In objective-c it looks like this:

#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

I need something like this with Swift, is it possible?

Please, show work example.
Reply

#2
For one-liner guy, no need to use the creepy swift extension

Swift 5.7.3

import CryptoKit

func mysha1(_ str:String) -> String {

return Insecure.SHA1.hash(data: str.data(using: String.Encoding.utf8)!).map
{ String(format: "%02x", $0) }.joined()

}
Reply

#3
A version for Swift 5 that uses CryptoKit on iOS 13 and falls back to CommonCrypto otherwise:

```swift
import CommonCrypto
import CryptoKit
import Foundation

private func hexString(_ iterator: Array<UInt8>.Iterator) -> String {
return iterator.map { String(format: "%02x", $0) }.joined()
}

extension Data {

public var sha1: String {
if #available(iOS 13.0, *) {
return hexString(Insecure.SHA1.hash(data: self).makeIterator())
} else {
var digest = [UInt8](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
self.withUnsafeBytes { bytes in
_ = CC_SHA1(bytes.baseAddress, CC_LONG(self.count), &digest)
}
return hexString(digest.makeIterator())
}
}

}
```

Usage:

```
let string = "The quick brown fox jumps over the lazy dog"
let hexDigest = string.data(using: .ascii)!.sha1
assert(hexDigest == "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12")
```

Also available via Swift package manager:

[To see links please register here]

Reply

#4
With `CryptoKit` added in iOS13, we now have native Swift API:

```swift
import Foundation
import CryptoKit

// CryptoKit.Digest utils
extension Digest {
var bytes: [UInt8] { Array(makeIterator()) }
var data: Data { Data(bytes) }

var hexStr: String {
bytes.map { String(format: "%02X", $0) }.joined()
}
}

func example() {
guard let data = "hello world".data(using: .utf8) else { return }
let digest = Insecure.SHA1.hash(data: data)
print(digest.data) // 20 bytes
print(digest.hexStr) // 2AAE6C35C94FCFB415DBE95F408B9CE91EE846ED
}
```
Reply

#5
Your Objective-C code (using a `NSString` category) can be directly translated to Swift
(using a `String` extension).

First you have to create a "bridging header" and add

#import <CommonCrypto/CommonCrypto.h>

Then:

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())

This can be written slightly shorter and Swifter as

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)
}
}

**Update for 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("")
}
}

To return a Base-64 encoded string instead of a hex encoded string,
just replace

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

with

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


**Update for 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()
}
}

To return a Base-64 encoded string instead of a hex encoded string,
just replace

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

by

return Data(bytes: digest).base64EncodedString()

**Update for Swift 4:**

The bridging header file is no longer needed, one can `import CommonCrypto` instead:

import CommonCrypto

extension 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()
}
}

**Update for Swift 5:**

The `Data.withUnsafeBytes()` method now calls the closure with an `UnsafeRawBufferPointer` to, and `baseAddress` is used to pass the initial address to the C function:

import CommonCrypto

extension 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()
}
}
Reply

#6
Yes, it's possible, copy this class into your project.
[

[To see links please register here]

][1]

And it will be easy like:

SHA1.hexString(from: "myPhrase" )!

**Tested for swift 3 and swift 4.**

[1]:

[To see links please register here]

Reply

#7
We can extract logic for encrypting string using sha1 for three steps:

1. Convert string to Data object
2. Encrypt data using SHA1 function to Data
3. Convert data object to hex string

IMHO it's much more readable and this version doesn't require NSData.

extension String {

var sha1: String {
guard let data = data(using: .utf8, allowLossyConversion: false) else {
// Here you can just return empty string or execute fatalError with some description that this specific string can not be converted to data
}
return data.digestSHA1.hexString
}

}

fileprivate extension Data {

var digestSHA1: Data {
var bytes: [UInt8] = Array(repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))

withUnsafeBytes {
_ = CC_SHA1($0, CC_LONG(count), &bytes)
}

return Data(bytes: bytes)
}

var hexString: String {
return map { String(format: "%02x", UInt8($0)) }.joined()
}

}
Reply

#8
To get the result as `NSData`, provided that you included `<CommonCrypto/CommonCrypto.h>` in your bridging header:

extension NSData {

func sha1() -> NSData? {
let len = Int(CC_SHA1_DIGEST_LENGTH)
let digest = UnsafeMutablePointer<UInt8>.alloc(len)
CC_SHA1(bytes, CC_LONG(length), digest)
return NSData(bytesNoCopy: UnsafeMutablePointer<Void>(digest), length: len)
}
}

Also uses proper pointer allocation. Invoke it like this:

myString.dataUsingEncoding(NSUTF8StringEncoding)?.sha1()

If you need a hex representation of `NSData` have a look at my other [answer](

[To see links please register here]

).
Reply

#9
Yes, it's possible: *make that objective-c code accessible from swift*

See [documentation](

[To see links please register here]

).

I would avoid rewriting it in swift if you won't get any benefit (such as using swift-specific features).

Also, in a project I am working on I used some objective-c code similar to yours to handle hashes. At beginning I started writing it in swift, then I realized that it was just easier and better to reuse old good obj-c.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through