fun main () {
var integers = mutableListOf(0)
for (x in 1..9) {
integers.add(x)
}
//for or while could be used in this instance
var lowerCase = listOf("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
var upperCase = listOf('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z')
println(integers)
println(lowerCase)
println(upperCase)
//Note that for the actual program, it is also vital that I use potential punctuation
val passwordGeneratorKey1 = Math.random()*999
val passwordGeneratorKey2 = passwordGeneratorKey1.toInt()
var passwordGeneratorL1 = lowerCase[(Math.random()*lowerCase.size).toInt()]
var passwordGeneratorL2 = lowerCase[(Math.random()*lowerCase.size).toInt()]
var passwordGeneratorL3 = lowerCase[(Math.random()*lowerCase.size).toInt()]
var passwordGeneratorU1 = upperCase[(Math.random()*upperCase.size).toInt()]
var passwordGeneratorU2 = upperCase[(Math.random()*upperCase.size).toInt()]
var passwordGeneratorU3 = upperCase[(Math.random()*upperCase.size).toInt()]
val password = passwordGeneratorKey2.toString()+passwordGeneratorL1+passwordGeneratorL2+passwordGeneratorL3+passwordGeneratorU1+passwordGeneratorU2+passwordGeneratorU3
println(password)
//No, this isn't random, but it's pretty close to it
//How do I now run through every possible combination of the lists //lowerCase, integers, and upperCase?
}
How do I run through every possible permutation to eventually solve for the randomly generated password? This is in Kotlin.
I think you should append all the lists together and then draw from it by random index, this way you ensure that position of numbers, lower cases and uppercases is random too. Also you don't need to write all the characters, you can use Range which generates them for you.
fun main() {
val allChars = mutableListOf<Any>().apply {
addAll(0..9) // creates range from 0 to 9 and adds it to a list
addAll('a'..'z') // creates range from a to z and adds it to a list
addAll('A'..'Z') // creates range from A to Z and adds it to a list
}
val passwordLength = 9
val password = StringBuilder().apply {
for (i in 0 until passwordLength) {
val randomCharIndex =
Random.nextInt(allChars.lastIndex) // generate random index from 0 to lastIndex of list
val randomChar = allChars[randomCharIndex] // select character from list
append(randomChar) // append char to password string builder
}
}.toString()
println(password)
}
Even shorter solution can be achieved using list methods
fun main() {
val password = mutableListOf<Any>()
.apply {
addAll(0..9) // creates range from 0 to 9 and adds it to a list
addAll('a'..'z') // creates range from a to z and adds it to a list
addAll('A'..'Z') // creates range from A to Z and adds it to a list
}
.shuffled() // shuffle the list
.take(9) // take first 9 elements from list
.joinToString("") // join them to string
println(password)
}
As others pointed out there are less painful ways to generate the initial password in the format of: 1 to 3 digits followed by 3 lowercase characters followed by 3 uppercase characters.
To brute force this password, you will need to consider all 3-permutations of "a..z" and all 3-permitations of "A..Z". In both cases the number of such 3-permutations is 15600 = 26! / (26-3)!. In worst case you will have to examine 1000 * 15600 * 15600 combination, half of this on the average.
Probably doable in a few hours with the code below:
import kotlin.random.Random
import kotlin.system.exitProcess
val lowercaseList = ('a'..'z').toList()
val uppercaseList = ('A'..'Z').toList()
val lowercase = lowercaseList.joinToString(separator = "")
val uppercase = uppercaseList.joinToString(separator = "")
fun genPassword(): String {
val lowercase = lowercaseList.shuffled().take(3)
val uppercase = uppercaseList.shuffled().take(3)
return (listOf(Random.nextInt(0, 1000)) + lowercase + uppercase).joinToString(separator = "")
}
/**
* Generate all K-sized permutations of str of length N. The number of such permutations is:
* N! / (N-K)!
*
* For example: perm(2, "abc") = [ab, ac, ba, bc, ca, cb]
*/
fun perm(k: Int, str: String): List<String> {
val nk = str.length - k
fun perm(str: String, accumulate: String): List<String> {
return when (str.length == nk) {
true -> listOf(accumulate)
false -> {
str.flatMapIndexed { i, c ->
perm(str.removeRange(i, i + 1), accumulate + c)
}
}
}
}
return perm(str, "")
}
fun main() {
val password = genPassword().also { println(it) }
val all3LowercasePermutations = perm(3, lowercase).also { println(it) }.also { println(it.size) }
val all3UppercasePermutations = perm(3, uppercase).also { println(it) }.also { println(it.size) }
for (i in 0..999) {
println("trying $i")
for (l in all3LowercasePermutations) {
for (u in all3UppercasePermutations) {
if ("$i$l$u" == password) {
println("found: $i$l$u")
exitProcess(0)
}
}
}
}
}
Hi I am writing an app in kotlin and need to decompose a number into powers of 2.
I have already done this in c#, PHP and swift but kotlin works differently somehow.
having researched this I believe it is something to do with the numbers in my code going negative somewhere and that the solution lies in declaring one or more of the variable as "Long" to prevent this from happening but i have not been able to figure out how to do this.
here is my code:
var salads = StringBuilder()
var value = 127
var j=0
while (j < 256) {
var mask = 1 shl j
if(value != 0 && mask != 0) {
salads.append(mask)
salads.append(",")
}
j += 1
}
// salads = (salads.dropLast()) // removes the final ","
println("Salads = $salads")
This shoud output the following:
1,2,4,8,16,32,64
What I actually get is:
1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,
Any ideas?
This works for the one input that you specified, at the very least:
fun powersOfTwo(value :Long): String {
val result = ArrayList<String>()
var i = 0
var lastMask = 0
while (lastMask < value) {
val mask = 1 shl i
if (value != 0.toLong() && mask < value) {
result.add(mask.toString())
}
lastMask = mask
i += 1
}
return result.joinToString(",")
}
Ran it in a unit test:
#Test
fun addition_isCorrect() {
val result = powersOfTwo(127)
assertEquals("1,2,4,8,16,32,64", result)
}
Test passed.
You can get a list of all powers of two that fit in Int and test each of them for whether the value contains it with the infix function and:
val value = 126
val powersOfTwo = (0 until Int.SIZE_BITS).map { n -> 1 shl n }
println(powersOfTwo.filter { p -> value and p != 0}.joinToString(","))
// prints: 2,4,8,16,32,64
See the entire code in Kotlin playground: https://pl.kotl.in/f4CZtmCyI
Hi I finally managed to get this working properly:
fun decomposeByTwo(value :Int): String {
val result = ArrayList<String>()
var value = value
var j = 0
while (j < 256) {
var mask = 1 shl j
if ((value and mask) != 0) {
value -= mask
result.add(mask.toString())
}
j += 1
}
return result.toString()
}
I hope this helps someone trying to get a handle on bitwise options!
Somehow you want to do the "bitwise AND" of "value" and "mask" to determine if the j-th bit of "value" is set. I think you just forgot that test in your kotlin implementation.
The below code will look for "=" and then split them. If there's no "=", filter them away first
myPairStr.asSequence()
.filter { it.contains("=") }
.map { it.split("=") }
However seeing that we have both
.filter { it.contains("=") }
.map { it.split("=") }
Wonder if there's a single operation that could combine the operation instead of doing it separately?
You can use mapNotNull instead of map.
myPairStr.asSequence().mapNotNull { it.split("=").takeIf { it.size >= 2 } }
The takeIf function will return null if the size of the list returned by split method is 1 i.e. if = is not present in the string. And mapNotNull will take only non null values and put them in the list(which is finally returned).
In your case, this solution will work. In other scenarios, the implementation(to merge filter & map) may be different.
I see your point and under the hood split is also doing an indexOf-check to get the appropriate parts.
I do not know of any such function supporting both operations in a single one, even though such a function would basically just be similar to what we have already for the private fun split-implementation.
So if you really want both in one step (and require that functionality more often), you may want to implement your own splitOrNull-function, basically copying the current (private) split-implementation and adapting mainly 3 parts of it (the return type List<String>?, a condition if indexOf delivers a -1, we just return null; and some default values to make it easily usable (ignoreCase=false, limit=0); marked the changes with // added or // changed):
fun CharSequence.splitOrNull(delimiter: String, ignoreCase: Boolean = false, limit: Int = 0): List<String>? { // changed
require(limit >= 0, { "Limit must be non-negative, but was $limit." })
var currentOffset = 0
var nextIndex = indexOf(delimiter, currentOffset, ignoreCase)
if (nextIndex == -1 || limit == 1) {
if (currentOffset == 0 && nextIndex == -1) // added
return null // added
return listOf(this.toString())
}
val isLimited = limit > 0
val result = ArrayList<String>(if (isLimited) limit.coerceAtMost(10) else 10)
do {
result.add(substring(currentOffset, nextIndex))
currentOffset = nextIndex + delimiter.length
// Do not search for next occurrence if we're reaching limit
if (isLimited && result.size == limit - 1) break
nextIndex = indexOf(delimiter, currentOffset, ignoreCase)
} while (nextIndex != -1)
result.add(substring(currentOffset, length))
return result
}
Having such a function in place you can then summarize both, the contains/indexOf and the split, into one call:
myPairStr.asSequence()
.mapNotNull {
it.splitOrNull("=") // or: it.splitOrNull("=", limit = 2)
}
Otherwise your current approach is already good enough. A variation of it would just be to check the size of the split after splitting it (basically removing the need to write contains('=') and just checking the expected size, e.g.:
myPairStr.asSequence()
.map { it.split('=') }
.filter { it.size > 1 }
If you want to split a $key=$value-formats, where value actually could contain additional =, you may want to use the following instead:
myPairStr.asSequence()
.map { it.split('=', limit = 2) }
.filter { it.size > 1 }
// .associate { (key, value) -> key to value }