Convert string to base64 in Swift 3 - swift

let strsize = 10_000_000
let tries = 100
var longstring:String = "a"
for i in 1...strsize {
longstring += "a"
}
for i in 1..<2 {
let basestring = NSData(base64EncodedString: longstring, options: .IgnoreUnknownCharacters)
print(basestring)
}
Writing a code in command prompt. What is the correct code to write for Swift 3 which I been getting use of unresolved identifier NSData . Most of the tutorials on encoding string to base64 aren't working.
This is working for you on Linux or Mac?
http://studyswift.blogspot.sg/2016/03/convert-nsdatauint8-to-base64-in-swift.html

Use this instead:
let longstring = "test123"
if let data = (longstring).data(using: String.Encoding.utf8) {
let base64 = data.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0))
print(base64)// dGVzdDEyMw==\n
}

this string extention can help .
extension String {
//Base64 decode
func fromBase64() -> String? {
guard let data = Data(base64Encoded: self) else {
return nil
}
return String(data: data, encoding: .utf8)
}
//Base64 encode
func toBase64() -> String {
return Data(self.utf8).base64EncodedString()
}
}
how to use.
let str = "Hello World"
str.toBase64().fromBase64()

In Swift 4.2 and Xcode 10.1
//Base64 encoding
let data = combinedString.data(using: .utf8)//Here combinedString is your string
let encodingString = data?.base64EncodedString()
print(encodingString!)
// OR Single line of code
let encodingString = combinedString.data(using: .utf8)?.base64EncodedString()//Here combinedString is your string
print(encodingString!)

Related

Decoding Base64 in Swift Returns nil

I have been trying to implement Coinbase API in my application that is built using swift 5 and xcode. Whenever I try to convert this base64 encoded data to Normal string, it returns nil.
Here is the string
fI5GtCKFF+O8j8uJlJVGxIvolVUUrVMT9GBouxlpEOUXmaGbwQvHt0z8kK0fUwQaKa45KUOLWHP/CQaM70bhdQ==
Below are the answers i've tried
extension String {
func base64Encoded() -> String? {
return data(using: .utf8)?.base64EncodedString()
}
func base64Decoded() -> String? {
var st = self;
print(st.count)
let remainder = self.count % 4
if remainder > 0 {
st = self.padding(toLength: self.count + 4 - remainder,
withPad: "=",
startingAt: 0)
}
print(st.count)
guard let d = Data(base64Encoded: st, options: .ignoreUnknownCharacters) else{
return nil
}
return String(data: d, encoding: .utf8)
}
}
THE DIFFERENCE
let base64Decoded = Data(base64Encoded: "fI5GtCKFF+O8j8uJlJVGxIvolVUUrVMT9GBouxlpEOUXmaGbwQvHt0z8kK0fUwQaKa45KUOLWHP/CQaM70bhdQ==")!
let sign = HMAC.sign(data: "1".toData()!, algorithm: .sha256, key: base64Decoded)
let signData = sign.base64EncodedString()
The result i receive: vBZ+Z63rFqNmU61yrd91PGQB8f1iqocWkLlAev5XJOc=
It's different from: https://www.liavaag.org/English/SHA-Generator/HMAC/
Link to result There's is the correct output. What am i missing or doing wrong ?

Decrypt data using AES.GCM.SealedBox in Swift

I am trying to decrypt data using AES.GCM.The encrypted data works fine but when I try to decrypt the data using the same key it gives authentication error.
Below is the code to decrypt
func decryptData(decryptToData: Data, key: SymmetricKey) -> String {
var decryptedString: String!
let combinedData = decryptToData // Previous sealed bo
let sealedBoxToOpen = try! AES.GCM.SealedBox(combined: decryptToData)
if let decryptedData = try? AES.GCM.open(sealedBoxToOpen, using: key) {
decryptedString = String(data: decryptedData, encoding: .utf8)!
print(decryptedString)
} else {
print("error", CryptoKitError.self)
// Ouch, doSomething() threw an error.
}
return decryptedString
}
The following is my encryption code
let iv = AES.GCM.Nonce()
var encryptedData: Data!
let key = SymmetricKey(size: .bits128)
func encryptData(encryptString: String, key: SymmetricKey) -> Data {
var encryptedData: Data?
do {
let datatoEncrypt1 = encryptString.data(using: .utf8)!
let mySealedBox = try AES.GCM.seal(datatoEncrypt1, using: key, nonce: iv)
encryptedData = mySealedBox.combined
} catch {
print("Error")
}
return encryptedData
}
import XCTest
import CryptoKit
import Foundation
class CryptoKitUnitTest: XCTestCase {
func testEncryptandDecrypt(){
let secret = "my-256-bit-secret-my-secret-my-s"
let key = SymmetricKey(data: secret.data(using: .utf8)!)
let plain = "Say hello to my little friend!"
let nonce = try! AES.GCM.Nonce(data: Data(base64Encoded: "fv1nixTVoYpSvpdA")!)
// Encrypt
let sealedBox = try! AES.GCM.seal(plain.data(using: .utf8)!, using: key, nonce: nonce)
let ciphertext = sealedBox.ciphertext.base64EncodedString()
print("ciphertext: \(ciphertext)") // bWtTZkPAu7oXpQ3QpHvoTvc4NQgDTIycXHFJWvjk
let sealedBoxToDecrypt = try! AES.GCM.SealedBox(nonce: nonce,
ciphertext: Data(base64Encoded: ciphertext)!,
tag: sealedBox.tag)
let decrypted = try! AES.GCM.open(sealedBoxToDecrypt, using: key)
print(String(decoding: decrypted, as: UTF8.self))
}
func testEncryptandDecryptFirstWay() {
let keyStr = "d5a423f64b607ea7c65b311d855dc48f36114b227bd0c7a3d403f6158a9e4412"
let key = SymmetricKey(data: Data(hex:keyStr))
let nonceData = Data(hex: "131348c0987c7eece60fc0bc")
let nonce: AES.GCM.Nonce = try! AES.GCM.Nonce(data: nonceData)
let plain = "This is first cypto graphy method"
var decyptedStr = ""
if let encyptedData = plain.asData.encrypt(nonce: nonce, key: key) {
decyptedStr = encyptedData.decrypt(nonce: nonce, key: key)
}
XCTAssertEqual(plain, decyptedStr)
}
}
extension Data {
func encrypt(nonce: AES.GCM.Nonce, key: SymmetricKey) ->Data?{
// Encrypt
do {
let sealedBox = try AES.GCM.seal(self, using: key, nonce: nonce)
let cipherText = sealedBox.ciphertext.base64EncodedString()
let tag = sealedBox.tag
let tagPlusCipherText = tag + cipherText.asData
return tagPlusCipherText
}
catch let exceptionInfo {
debugPrint("Encrypt exception Info: \(exceptionInfo)")
}
return nil
}
func decrypt(nonce: AES.GCM.Nonce, key: SymmetricKey) -> String{
let tag = self.subtract(0, 16)
let cipherTextData = self.subtract(tag.count, self.count - tag.count)
let cipherText = cipherTextData.asString
// Decrypt
var decodeStr: String = ""
do {
let sealedBoxToDecrypt = try AES.GCM.SealedBox(nonce: nonce,
ciphertext: Data(base64Encoded: cipherText)!,
tag: tag)
let decrypted = try AES.GCM.open(sealedBoxToDecrypt, using: key)
decodeStr = String(decoding: decrypted, as: UTF8.self)
} catch let exceptionInfo {
debugPrint("Decrypt exception info: \(exceptionInfo)")
}
return decodeStr
}
public func subtract(_ start: Int, _ length: Int) ->Data {
precondition(self.count >= start + length,
"Invalid data range range. trying to find out of bound data")
let allBytes = Array(Data(bytes: self.bytes, count: self.count))
let partBytes = Array(allBytes[start..<start + length])
let dataPart = Data(bytes: partBytes, count: partBytes.count)
return dataPart
}
var asString: String {
let str = String(decoding: self, as: UTF8.self)
return str
}
}
extension String {
var asData: Data {
return self.data(using: .utf8) ?? Data()
}
}

iOS - Converting String to Double

So i am fetching from fire base config data and trying to manipulate it as so.
This is my struct :
struct FireBaseConfiguration: Codable {
var updateTime: String = ""
var iOSMinVersionForceUpdate: String = ""
var iOSMinVersionMessageUpdate: String = ""
var iOSMinFirmwareVersion: String = ""
var privacyPolicyUrlFireBase: String = ""
var termOfUseUrlFireBase: String = ""
}
This is my parser method:
func fireBaseConfigVersionMapParser(dataString: String, version: String) -> FireBaseConfiguration? {
var fireBaseConfiguration: FireBaseConfiguration?
let data = dataString.data(using: .utf8)!
do {
if let jsonArray = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? NSDictionary {
let model = jsonArray.object(forKey: version)
let data = try JSONSerialization.data(withJSONObject: model!, options: .prettyPrinted)
do {
let parsedModel = try JSONDecoder().decode(FireBaseConfiguration.self, from: data)
print("parsedModel is: \(parsedModel)")
fireBaseConfiguration = parsedModel
} catch let error{
print(error)
}
} else {
print("bad json")
}
} catch let error{
print(error)
}
return fireBaseConfiguration
}
And this is the implementation in the vc:
self.remoteConfig?.fetch(withExpirationDuration: 0, completionHandler: { [unowned self] (status, error) in
if status == .success {
self.remoteConfig?.activateFetched()
guard let configVersionMap = self.remoteConfig?.configValue(forKey: "iOSConfigVersionMap").stringValue else { return }
if let configModel = self.parser.fireBaseConfigVersionMapParser(dataString: configVersionMap, version: self.getCurrentAppVersion()!) {
print(configModel)
print(configModel.iOSMinVersionForceUpdate)
print(configModel.iOSMinVersionMessageUpdate)
var doubleForceUpdate = Double(configModel.iOSMinVersionForceUpdate)
var doubleMessageUpdate = Double(configModel.iOSMinVersionMessageUpdate)
print(doubleForceUpdate)
print(doubleMessageUpdate)
}
} else {
print("Config not fetched")
print("Error: \(error?.localizedDescription ?? "No error available.")")
}
})
so the prints are so:
FireBaseConfiguration(updateTime: "13/7/2018", iOSMinVersionForceUpdate: "1.0.2", iOSMinVersionMessageUpdate: "1.0.2", iOSMinFirmwareVersion: "1.0.1", privacyPolicyUrlFireBase: "https://www.name.com/corporate/privacy-policy", termOfUseUrlFireBase: "https://www.name.com/corporate/terms-of-use")
1.0.2
1.0.2
nil
nil
any ideas?
It is a simple String, but it's not actually a valid Double (Double values do not have two decimal places). So this is why it is failing.
What I think you actually need is the ability to compare version numbers, there are a number of other answers on the site that can show you how to do this:
Compare two version strings in Swift
Compare version numbers in Objective-C
So you can just keep your version numbers as a String

How to convert a numeric character reference to a decimal in Swift?

How to convert this type of string "8.37" to its decimal value 8.37?
I'm using Swift 4.
I tried:
extension String {
func hexToFloat() -> Float {
var toInt = Int32(truncatingIfNeeded: strtol(self, nil, 16))
var float:Float32!
memcpy(&float, &toInt, MemoryLayout.size(ofValue: float))
return float
}
}
[...]
let myString = "8.37"
let myDecimal = myString.hexToFloat()
print(myDecimal) // prints 0.0
(From here)
There's no straight forward way (at least to my knowledge). But you can do something like below to get the value. Please note that the code below is in Swift 3. You may have to change the syntax.
extension String {
func hexToFloat() -> Float {
let data = myString.data(using: .utf8)
let options: [String: Any] = [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType]
do {
let attributedString = try NSAttributedString(data: data!, options: options, documentAttributes: nil)
return Float(attributedString.string)!
} catch {
return 0
}
}
}
let myString = "8.37"
let myDecimal = myString.hexToFloat()
print(myDecimal) // prints 8.37

Hex string to text conversion - swift 3

I'm trying to convert an hex string to text.
This is what i have:
// Str to Hex
func strToHex(text: String) -> String {
let hexString = text.data(using: .utf8)!.map{ String(format:"%02x", $0) }.joined()
return "0x" + hexString
}
and I'm trying to reverse the hex string that I've just created back to the original one.
So, for example:
let foo: String = strToHex(text: "K8") //output: "0x4b38"
and i would like to do something like
let bar: String = hexToStr(hex: "0x4b38") //output: "K8"
can someone help me?
Thank you
You probably can use something like this:
func hexToStr(text: String) -> String {
let regex = try! NSRegularExpression(pattern: "(0x)?([0-9A-Fa-f]{2})", options: .caseInsensitive)
let textNS = text as NSString
let matchesArray = regex.matches(in: textNS as String, options: [], range: NSMakeRange(0, textNS.length))
let characters = matchesArray.map {
Character(UnicodeScalar(UInt32(textNS.substring(with: $0.rangeAt(2)), radix: 16)!)!)
}
return String(characters)
}
NSRegularExpression is overkill for the job. You can convert the string to byte array by grabbing two characters at a time:
func hexToString(hex: String) -> String? {
guard hex.characters.count % 2 == 0 else {
return nil
}
var bytes = [CChar]()
var startIndex = hex.index(hex.startIndex, offsetBy: 2)
while startIndex < hex.endIndex {
let endIndex = hex.index(startIndex, offsetBy: 2)
let substr = hex[startIndex..<endIndex]
if let byte = Int8(substr, radix: 16) {
bytes.append(byte)
} else {
return nil
}
startIndex = endIndex
}
bytes.append(0)
return String(cString: bytes)
}
Solution that supports also special chars like emojis etc.
static func hexToPlain(input: String) -> String {
let pairs = toPairsOfChars(pairs: [], string: input)
let bytes = pairs.map { UInt8($0, radix: 16)! }
let data = Data(bytes)
return String(bytes: data, encoding: .utf8)!
}