Swift Simple XOR Encryption - swift

I am trying to do a simple xor encryption routine in Swift. I know this is not a particularly secure or great method but I just need it to be simple. I know how the code is implemented in Javascript I'm just having trouble translating it to Swift.
Javascript:
function xor_str()
{
var to_enc = "string to encrypt";
var xor_key=28
var the_res="";//the result will be here
for(i=0;i<to_enc.length;++i)
{
the_res+=String.fromCharCode(xor_key^to_enc.charCodeAt(i));
}
document.forms['the_form'].elements.res.value=the_res;
}
Any help you could provide would be great, thanks!

I would propose an extension to String like this.
extension String {
func encodeWithXorByte(key: UInt8) -> String {
return String(bytes: map(self.utf8){$0 ^ key}, encoding: NSUTF8StringEncoding)!
}
From the inside out,
The call to self.utf8 creates a byte array, [UInt8], from the string
map() is called on each element and XOR'ed with the key value
A new String object is created from the XOR'ed byte array
Here is my Playground screen capture.
UPDATED: For Swift 2.0
extension String {
func encodeWithXorByte(key: UInt8) -> String {
return String(bytes: self.utf8.map{$0 ^ key}, encoding: NSUTF8StringEncoding) ?? ""
}
}

I can't answer with a comment yet, but Price Ringo, i noticed a couple problems with your sandbox..
the last line has 2 errors, you should actually XOR it with the original encrypted UInt8 and you are not "decoding" the encrypted string..
you have...
println(str.encodeWithXorByte(0))
where you should have..
println(encrypted.encodeWithXorByte(28))

Related

Swift return different Types from a function

Completing some old HackerRank challenges.
Some of these appear to be broken - for example "Fair Rations" gives us the following function signature (note: The capital for the parameter is not my fault, it is not changeable within this context.
func fairRations(B: [Int]) -> Int {
// Enter code answer code here
}
Now the problem test cases (the details of the problem are not important here) require that we return an
Int
(i.e. 4) for some test cases, and a
String
(i.e. "NO") for other tests.
So I need to return either a String, or an Int depending upon my answers. I've tried to return an enum, but I can't make any changes to the HackerRank tests - also returning any
like:
func fairRations(B: [Int]) -> Any {
// Enter code answer code here
}
will not work as Any is not implicitly convertible to either a String or an Int.
The HackerRank problem is here: https://www.hackerrank.com/challenges/fair-rations/problem
To clarify in response to Joakim Danielson, the problem description implies that you can output "NO" to the console, but that is not actually true (see screenshot below).
Is it possible to have a function that returns both a String and an Int in Swift?
Just change the function to return a String. Keep in mind that integers can be represented as a string as well. The string "4" represents the number 4.
I changed the function to this in hacker rank:
func fairRations(B: [Int]) -> String {
return "4"
}
And it passed this test:
Basically,
If you want to return an integer x, just return x.description
If you want to return NO, just return "NO".
Both of the above values are strings.
Returning a String here works because the test calls the String(...) initialiser. And if you pass a string to that, it will still create the same string you passed in.
EDIT:
I tried editing the client code and it works. You can just return a Int? and do this:
if let result = fairRations(B: B) {
fileHandle.write(String(result).data(using: .utf8)!)
} else {
fileHandle.write("NO".data(using: .utf8)!)
}

Swift BitConverter.DoubleToInt64Bits Equivalent

I need Swift implementation of C# BitConverter.DoubleToInt64Bits(doubleValue).
I find C# implementantion on site is only
https://referencesource.microsoft.com/#mscorlib/system/bitconverter.cs
[SecuritySafeCritical]
public static unsafe long DoubleToInt64Bits(double value) {
/// some comments ....
Contract.Assert(IsLittleEndian, "This method is implemented assuming little endian with an ambiguous spec.");
return *((long *)&value);
}
in c# i have method:
public long EncodeValue(double doubleValue)
{
return BitConverter.DoubleToInt64Bits(doubleValue);
}
but I need the same functionality in Swift for ios.
Something like this:
func EncodeValue(doubleValue: Double)
{
return SwiftDoubleToInt64Bits(doubleValue)
}
The bitPattern property of Double returns an (unsigned) 64-bit integer with the same memory representation:
let doubleValue = 12.34
let encoded = doubleValue.bitPattern // UInt64
The reverse conversion is done with
let decoded = Double(bitPattern: encoded)
print(decoded) // 12.34
In the same way you can convert between Float and UInt32.
For a platform independent memory representation (e.g. “big endian”) use
let encodedBE = doubleValue.bitPattern.bigEndian
let decoded = Double(bitPattern: UInt64(bigEndian: encodedBE))

Swift 3 String has no member components [duplicate]

So I'm trying to prepare myself for coding interviews by doing HackerRank's test case samples. If you're familiar with the process, you usually take a standard input that has various lines of strings and you extract the information based on what the question is asking. I have come across numerous questions where they will give you a line (as a String) with n number of integers separated by a space (i.e. 1 2 3 4 5). In order to solve the problem I need to extrapolate an array of Int ([Int]) from a String. I came up with this nifty method:
func extractIntegers(_ s: String) -> [Int] {
let splits = s.characters.split { [" "].contains(String($0)) }
return splits.map { Int(String($0).trimmingCharacters(in: .whitespaces))! }
}
So I code it in my Playground and it works fantastic, I even run multiple test cases I make up, and they all pass with flying colors...then I copy the code to HackerRank and try running it for submission. And I get this:
solution.swift:16:29: error: value of type 'String' has no member 'trimmingCharacters'
return splits.map { Int(String($0).trimmingCharacters(in: .whitespaces))! }
So... okay maybe HR hasn't updated everything for Swift 3 yet. No big deal! I have an idea for an even cleaner solution! Here it is:
func extractIntegers(_ s: String) -> [Int] {
return s.components(separatedBy: " ").map { Int($0)! }
}
....AAAAANDDD of course:
solution.swift:15:12: error: value of type 'String' has no member 'components'
return s.components(separatedBy: " ").map { Int($0)! }
So now I'm forced to use a really sloppy method where I loop through all the characters, check for spaces, append substrings from ranges between spaces into an array, and then map that array and return it.
Does anyone have any other clean ideas to work around HR's inadequacies with Swift? I would like any recommendations I can get!
Thanks in advance!
The String methods
func trimmingCharacters(in set: CharacterSet) -> String
func components(separatedBy separator: String) -> [String]
are actually methods of the NSString class, defined in the Foundation
framework, and "bridged" to Swift. Therefore, to make your code compile,
you have go add
import Foundation
But a slightly simplified version of your first method compiles
with pure Swift, without importing Foundation. I handles leading, trailing, and intermediate whitespace:
func extractIntegers(_ s: String) -> [Int] {
let splits = s.characters.split(separator: " ").map(String.init)
return splits.map { Int($0)! }
}
let a = extractIntegers(" 12 234 -567 4 ")
print(a) // [12, 234, -567, 4]
Update for Swift 4 (and simplified):
func extractIntegers(_ s: String) -> [Int] {
return s.split(separator: " ").compactMap { Int($0) }
}

Mocking a String-class method in Swift

I've got some Swift 2.0 code, for which I'm trying to achieve 100% code coverage. I'm doing some JSON handling, part of which looks like so:
guard let jsonData = jsonText.dataUsingEncoding(NSUTF8StringEncoding) else {
throw ErrorCode.JSONEncodingFailure
}
I don't think there's a real-world case in which any string can't be encoded as UTF-8, but I don't want to open myself up to a crashing error either, so that code must remain. How can I mock the jsonText object to return nil for dataUsingEncoding()?
The closest I've come is to subclass NSString like so:
public class BadString: NSString {
public override var length: Int {
get {
return 5
}
}
public override func characterAtIndex(index: Int) -> unichar {
return 0
}
public override func dataUsingEncoding(encoding: NSStringEncoding) -> NSData? {
return nil
}
}
Here's the problem, though. In order for my mock implementation to be used, I have to define jsonText (a function parameter) as an NSString, rather than String, which feels wrong for an all-Swift codebase. With it defined as a Swift String, I have to cast my BadString to that type, and it uses the String implementation instead of my own.
Is there another (clean) way to achieve this?
You will be hard-pressed to find a string that cannot be encoded using UTF-8! As long as you know that is the encoding you will be using, I would suggest that you not worry about testing the "encoding failure" case.
However, if you still desire to test it then I recommend making one of the following changes in order to allow you to do so:
(1) change the way you are thinking about the 'failure': if you know that the string you are encoding will always be non-empty, then broaden the guard to also require that the encoded data has length > 0, e.g. =>
guard let jsonData = jsonText.dataUsingEncoding(NSUTF8StringEncoding)
where jsonData.length > 0 else {
throw ErrorCode.JSONEncodingFailure
}
...using this idea, you can now use an empty string for jsonText and trigger this code path (assuming that an empty string would also satisfy your definition of 'failure' here)
(2) store your string encoding value in a variable (let's call it stringEncoding) that you can access during your test setup, and then test this using incompatible values for jsonText and stringEncoding, e.g. =>
var jsonText = "🙈"
let stringEncoding = NSASCIIStringEncoding
...I guarantee that jsonText.dataUsingEncoding(stringEncoding) will return nil in this case :)
Happy Testing! I hope this helps!

Swift convert string to UnsafeMutablePointer<Int8>

I have a C function mapped to Swift defined as:
func swe_set_eph_path(path: UnsafeMutablePointer<Int8>) -> Void
I am trying to pass a path to the function and have tried:
var path = [Int8](count: 1024, repeatedValue: 0);
for i in 0...NSBundle.mainBundle().bundlePath.lengthOfBytesUsingEncoding(NSUTF16StringEncoding)-1
{
var range = i..<i+1
path[i] = String.toInt(NSBundle.mainBundle().bundlePath[range])
}
println("\(path)")
swe_set_ephe_path(&path)
but on the path[i] line I get the error:
'subscript' is unavailable: cannot subscript String with a range of
Int
swe_set_ephe_path(NSBundle.mainBundle().bundlePath)
nor
swe_set_ephe_path(&NSBundle.mainBundle().bundlePath)
don't work either
Besides not working, I feel there has got to be a better, less convoluted way of doing this. Previous answers on StackOverflow using CString don't seem to work anymore. Any suggestions?
Previous answers on StackOverflow using CString don't seem to work anymore
Nevertheless, UnsafePointer<Int8> is a C string. If your context absolutely requires an UnsafeMutablePointer, just coerce, like this:
let s = NSBundle.mainBundle().bundlePath
let cs = (s as NSString).UTF8String
var buffer = UnsafeMutablePointer<Int8>(cs)
swe_set_ephe_path(buffer)
Of course I don't have your swe_set_ephe_path, but it works fine in my testing when it is stubbed like this:
func swe_set_ephe_path(path: UnsafeMutablePointer<Int8>) {
println(String.fromCString(path))
}
In current version of Swift language you can do it like this (other answers are outdated):
let path = Bundle.main.bundlePath
let param = UnsafeMutablePointer<Int8>(mutating: (path as NSString).utf8String)
It’s actually extremely irritating of the library you’re using that it requires (in the C declaration) a char * path rather than const char * path. (this is assuming the function doesn’t mutate the input string – if it does, you’re in a whole different situation).
If it didn’t, the function would come over to Swift as:
// note, UnsafePointer not UnsafeMutablePointer
func swe_set_eph_path(path: UnsafePointer<Int8>) -> Void
and you could then rely on Swift’s implicit conversion:
let str = "blah"
swe_set_eph_path(str) // Swift implicitly converts Strings
// to const C strings when calling C funcs
But you can do an unsafe conversion quite easily, in combination with the withCString function:
str.withCString { cstr in
swe_set_eph_path(UnsafeMutablePointer(cstr))
}
I had a static library (someLibrary.a) written in C++ compiled for iOS.
The header file (someLibrary.h) had a function exposed like this:
extern long someFunction(char* aString);
The declaration in Swift looks like this:
Int someFunction(aString: UnsafeMutablePointer<Int8>)
I made an extension to String:
extension String {
var UTF8CString: UnsafeMutablePointer<Int8> {
return UnsafeMutablePointer((self as NSString).UTF8String)
}
}
So then I can call the method like so:
someFunction(mySwiftString.UTF8CString)
Update: Make String extension (swift 5.7)
extension String {
var UTF8CString: UnsafeMutablePointer<Int8> {
return UnsafeMutablePointer(mutating: (self as NSString).utf8String!)
}
}