How I can convert int to binary string swift? - swift

I have such int number:
266
I would like to convert it to binary string. In android I use such method:
Integer.toBinaryString(266)
and the output was:
000100001010
I ios I tried to use string with radix:
String(266, radix: 2)
but I got:
100001010
I found such question-answer and used such code:
func pad(string : String, toSize: Int) -> String {
var padded = string
for _ in 0..<(toSize - string.count) {
padded = "0" + padded
}
return padded
}
and:
pad(string: String(ResumeController.userData.edu!), toSize: 12)
and got:
000100001010
can you please explain why external function which added some 0s works similar to the kotlin one which is built-in? And also one more question - how I can get this number back from this binary string?

There is a function that can convert to integer Int("000100001010", radix: 2)
To append zeroes, use this:
let str = String(repeating: "0", count: amount)

Related

What is happening during the String.init

I found this example function that takes a integer and then sorts the number from largest to smallest. Example input: 12345 output: 54321. The solution works but I am trying to understand the String.init part. Could anyone explain what is going on?
func descendingOrder(of number: Int) -> Int {
let s = String(number).sorted().reversed()
return Int(s.compactMap(String.init).joined())!
}
s is of type ReversedCollection<[String.Element]> so it makes the conversion from String.Element to String this is the meaning of String.init inside loop of compactMap
When you see DataType.init you need to know that the item being looped is a paramter for the init of that type so loop occurs over the characters of the String s to make a new [String] as a result
Developer complicates the line , it could be simplified to this for netter understanding
func descendingOrder(of number: Int) -> Int {
let s = String(number).sorted().reversed() // sort and reverse the string descendinng
let arr = s.compactMap(String.init) // convert characters to array of strings
let joined = arr.joined() // join them in 1 string
let res = Int(joined)! // convert string to int
return res
}
OR as in comments
func descendingOrder(of number: Int) -> Int {
let s = String(number).sorted().reversed() // sort and reverse the string descendinng
let arr = s.map{ String($0) } // convert characters to array of strings
let joined = arr.joined() // join them in 1 string
let res = Int(joined)! // convert string to int
return res
}

How to convert my bytes data to Hex String and then Signed integer (32-bit) Two's complement from that ..?

I have a data like a bellow:
let data = Data(bytes: [206, 66, 49, 62])
Then I used this extension (from How to convert Data to hex string in swift) to convert to a hex string:
extension Data {
struct HexEncodingOptions: OptionSet {
let rawValue: Int
static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
}
func hexEncodedString(options: HexEncodingOptions = []) -> String {
let hexDigits = Array((options.contains(.upperCase) ? "0123456789ABCDEF" : "0123456789abcdef").utf16)
var chars: [unichar] = []
chars.reserveCapacity(2 * count)
for byte in self {
chars.append(hexDigits[Int(byte / 16)])
chars.append(hexDigits[Int(byte % 16)])
}
return String(utf16CodeUnits: chars, count: chars.count)
}
}
And then it is giving "ce42313e" as hex string. Now I am trying to convert this to Signed integer (32-bit) Two's complement .. I tried a couple of ways but not find anything perfectly.
When I give "ce42313e" in this bellow link under hex decimal the value is -834522818
http://www.binaryconvert.com/convert_signed_int.html
bellow is one of those I tried to convert "ce42313e" to int and it's giving me 3460444478 ..instead of -834522818 .
let str = value
let number = Int(str, radix: 16)
Please help out to get that value.
Int(str, radix: 16) interprets the string as the hexadecimal
representation of an unsigned number. You could convert it to
Int32 with
let data = Data(bytes: [206, 66, 49, 62])
let str = data.hexEncodedString()
print(str) // ce42313e
let number = Int32(truncatingBitPattern: Int(str, radix: 16)!)
print(number) // -834522818
But actually you don't need the hex representation for that purpose.
Your data is the big-endian representation of a signed 32-bit integer,
and this is how you can get the number from the data directly:
let data = Data(bytes: [206, 66, 49, 62])
let number = Int32(bigEndian: data.withUnsafeBytes { $0.pointee })
print(number) // -834522818

Swift 4 hex string to binary string

Noted that the old method to convert a hex string to a binary string has been removed from swift i.e. : String(hex, radix: 2) -> binary string
What is an alternative in swift 4?
You need first to convert your hexaString to an Array of Bytes [UInt8]. Then you can use String(_, radix:) to convert the bytes to binary. Note that if you would like to return a String instead of an array of strings [String] you would need to add leading zeros to make your binary strings length consistent (8 characters):
extension String {
typealias Byte = UInt8
var hexaToBytes: [Byte] {
var start = startIndex
return stride(from: 0, to: count, by: 2).compactMap { _ in // use flatMap for older Swift versions
let end = index(after: start)
defer { start = index(after: end) }
return Byte(self[start...end], radix: 16)
}
}
var hexaToBinary: String {
return hexaToBytes.map {
let binary = String($0, radix: 2)
return repeatElement("0", count: 8-binary.count) + binary
}.joined()
}
}
let hexString = "00ff01fe"
hexString.hexaToBinary // "00000000111111110000000111111110"
I don't recall any function that would convert a hex string to another string of arbitrary radix. Perhaps you are thinking about the initializer functions that convert between strings and integer values (and vice versa) using an arbitrary radix:
let hex = "00ff01fe"
let value = UInt64(hex, radix: 16)!
let binary = String(value, radix: 2)
let paddedBinary = repeatElement("0", count: 64 - binary.count) + binary
But that only applies when the hex string represents a 64 bit value, but it illustrates the basic idea. Convert to some integer type, and then convert back to binary, padding it out with zeros.
If you have a hex string that is longer than that, you cannot use the above. But you can map the individual characters of your hex string to numeric values, build binary representation of each, zero pad them, and use joined to concatenate them together:
let hex = "ffeeddccbbaa99887766554433221100"
let result = hex.compactMap { c -> String? in
guard let value = Int(String(c), radix: 16) else { return nil }
let string = String(value, radix: 2)
return repeatElement("0", count: 4 - string.count) + string
}.joined()

How can I generate a random unicode character in Swift?

My current attempts at creating a random unicode character generate have failed with errors such as those mentioned in my other question here. It's obviously not as simple as just generating a random number.
Question: How can I generate a random unicode character in Swift?
Unicode Scalar Value
Any Unicode code point except high-surrogate and low-surrogate code
points. In other words, the ranges of integers 0 to D7FF and E000
to 10FFFF inclusive.
So, I've made a small code's snippet. See below.
This code works
func randomUnicodeCharacter() -> String {
let i = arc4random_uniform(1114111)
return (i > 55295 && i < 57344) ? randomUnicodeCharacter() : String(UnicodeScalar(i))
}
randomUnicodeCharacter()
This code doesn't work!
let N: UInt32 = 65536
let i = arc4random_uniform(N)
var c = String(UnicodeScalar(i))
print(c, appendNewline: false)
I was a little bit confused with this and this. [Maximum value: 65535]
static func randomCharacters(withLength length: Int = 20) -> String {
let base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var randomString: String = ""
for _ in 0..<length {
let randomValue = arc4random_uniform(UInt32(base.characters.count))
randomString += "\(base[base.index(base.startIndex, offsetBy: Int(randomValue))])"
}
return randomString
}
Here you can modify length (Int) and use this for generating random characters.

Binary to hexadecimal in Swift

I have a string in binary (for example "00100100"), and I want it in hexadecimal (like "24").
Is there a method written to convert Binary to Hexadecimal in Swift?
A possible solution:
func binToHex(bin : String) -> String {
// binary to integer:
let num = bin.withCString { strtoul($0, nil, 2) }
// integer to hex:
let hex = String(num, radix: 16, uppercase: true) // (or false)
return hex
}
This works as long as the numbers fit into the range of UInt (32-bit or 64-bit,
depending on the platform). It uses the BSD library function strtoul() which converts a string to an integer according to a given base.
For larger numbers you have to process the input
in chunks. You might also add a validation of the input string.
Update for Swift 3/4: The strtoul function is no longer needed.
Return nil for invalid input:
func binToHex(_ bin : String) -> String? {
// binary to integer:
guard let num = UInt64(bin, radix: 2) else { return nil }
// integer to hex:
let hex = String(num, radix: 16, uppercase: true) // (or false)
return hex
}
let binaryInteger = 0b1
// Your binary number
let hexadecimalNum = String(binaryInteger, radix: 16)
// convert into string format in whatever base you want
For more information
let decimalInteger = 15 // prefix NONE
let binaryInteger = 0b10001 // prefix 0b
let octalInteger = 0o21 // prefix 0o
let hexadecimalInteger = 0x11 // prefix 0x