1 // Copyright 2022-present 650 Industries. All rights reserved.
2 
3 import CommonCrypto
4 import ABI47_0_0ExpoModulesCore
5 
6 public class CryptoModule: Module {
definitionnull7   public func definition() -> ModuleDefinition {
8     Name("ExpoCrypto")
9 
10     AsyncFunction("digestStringAsync", digestString)
11 
12     Function("digestString", digestString)
13   }
14 }
15 
digestStringnull16 private func digestString(algorithm: DigestAlgorithm, str: String, options: DigestOptions) throws -> String {
17   guard let data = str.data(using: .utf8) else {
18     throw LossyConversionException()
19   }
20 
21   let length = Int(algorithm.digestLength)
22   var digest = [UInt8](repeating: 0, count: length)
23 
24   data.withUnsafeBytes { bytes in
25     let _ = algorithm.digest(bytes.baseAddress, UInt32(data.count), &digest)
26   }
27 
28   switch options.encoding {
29   case .hex:
30     return digest.reduce("") { $0 + String(format: "%02x", $1) }
31   case .base64:
32     return Data(digest).base64EncodedString()
33   }
34 }
35 
36 private class LossyConversionException: Exception {
37   override var reason: String {
38     "Unable to convert given string without losing some information"
39   }
40 }
41