https://kotlinlang.org logo
#ios
Title
r

Robert Munro

10/07/2022, 12:41 PM
Hi, i am trying to implement this ios code example (base64 encode/decode) in kotlin - but am having trouble getting the syntax right https://stackoverflow.com/questions/18827798/how-to-decode-base64-string-to-nsstring-in-ios just wondering if anyone has tips i don't understand objc too well - but i understand the [] are a method call in this case. but i am wondering how to convert
NSString
->
NSData
in kotlin. Then it looks like the base64 encode : decode methods are in NSData? Sorry its a noob question i know ...
r

ribesg

10/07/2022, 12:52 PM
Why not use a library? Okio can do that. There is also https://github.com/saschpe/Kase64
r

Robert Munro

10/07/2022, 12:56 PM
yes maybe? seems like it should only be a couple lines of code though? as the platforms all have their own implementation. so possibly is better than introducing a dependency.
m

Matthew Kruk

10/07/2022, 12:56 PM
I use this:
Copy code
object Base64 {
    private const val BASE64_SET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    private val BASE64_REGEX = "[^="+BASE64_SET+"]".toRegex()

    val String.base64encoded: String get() {
        val pad = when (this.length % 3) {
            1 -> "=="
            2 -> "="
            else -> ""
        }
        var raw = this
        (1 .. pad.length).forEach { _ -> raw += 0.toChar() }
        return StringBuilder().apply {
            (raw.indices step 3).forEach { it ->
                val n: Int = (
                        0xFF.and(raw[ it ].code) shl 16) +
                        (0xFF.and(raw[it+1].code) shl  8) +
                        0xFF.and(raw[it+2].code
                        )

                listOf(
                    (n shr 18) and 0x3F,
                    (n shr 12) and 0x3F,
                    (n shr  6) and 0x3F,
                    n and 0x3F
                ).forEach { append(BASE64_SET[it]) }
            }
        }   .dropLast(pad.length)
            .toString() + pad
    }

    val String.base64decoded: String get() {
        if (this.length % 4 != 0) throw IllegalArgumentException(LOG_TAG + "Cannot decode: $this is not compliant with BASE64 length requirement.")
        val clean = this.replace(BASE64_REGEX, "").replace("=", "A")
        val padLength = this.filter {it == '='}.length
        return StringBuilder().apply {
            (clean.indices step 4).forEach {
                val n: Int = (
                        BASE64_SET.indexOf(clean[it]) shl 18) +
                        (BASE64_SET.indexOf(clean[it+1]) shl 12) +
                        (BASE64_SET.indexOf(clean[it+2]) shl  6) +
                        BASE64_SET.indexOf(clean[it+3]
                        )

                listOf<Int>(
                    0xFF.and(n shr 16),
                    0xFF.and(n shr  8),
                    0xFF.and(   n    )
                ).forEach { append(it.toChar()) }
            }
        }   .dropLast(padLength)
            .toString()
    }
}
r

Robert Munro

10/07/2022, 1:03 PM
ok thanks. I think i am still looking to use the ios platform method though. As that most efficient for ios (i guess)
and for my own education
r

ribesg

10/07/2022, 1:33 PM
I suppose one of the existing libs may use the platform implementation on iOS, maybe you could like at that code. Ktor has another implementation
n

Nikolay Kasyanov

10/07/2022, 1:43 PM
NSString -> NSData
can be achieved via the
.dataUsingEncoding(...)
method I presume
r

Robert Munro

10/10/2022, 11:42 AM
I ended up using the Kase64 library. thanks for the help ...
11 Views