2
votes

itérer sur les caractères de la chaîne dans kotlin

J'essaye d'écrire une boucle qui décomposera un modèle de chaînes et lui enverra 20 octets par itération dans kotlin.

fun verifySensor(template: String) {

    var previousValue = 0

    val iterationTimes = template.length / 20

    for (value in 1 until iterationTimes) {
        val templateByte = if (value == iterationTimes) {
            template.substring(previousValue until template.length - 1).toByteArray()
        } else {
            val subTemplate = template.substring(previousValue until (20 * value))
            subTemplate.toByteArray()
        }

        //Write the bytes to the sensor here
        writeToService(templateByte)
        previousValue += 20

        Log.i(TAG, "template >>> :: ${templateByte.toString(Charsets.UTF_8)}")


    }
    writeToService("VERIFY".toByteArray())


    Log.i(TAG, "Writing finger template in Byte")

}

Je reçois une sortie de >> p>

040c62008efa8675463a f40785d3877b854870d8 b61b85d342f747ffd1f3 86648a877410fa2b887e 074b6ec8d16c887c9578 e6f8358586bac3f70bff 41a587c04af9d9ef394d 88132cebfe17d6c2881a c19979fefae2889102ca f3cf8ac48889c8f86b68 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 000000000000725a7353 95257462355224a396f2 0f000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000

Mais je m'attends >>

040c62008efa8675463a f40785d3877b854870d8 b61b85d342f747ffd1f3 86648a877410fa2b887e 074b6ec8d16c887c9578 e6f8358586bac3f70bff 41a587c04af9d9ef394d 88132cebfe17d6c2881a c19979fefae2889102ca f3cf8ac48889c8f86b68 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 000000000000725a7353 95257462355224a396f2 0f000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 000000000000733d

Les deux dernières lignes de la sortie attendue sont omises

"00000000000000000000 000000000000733d "


0 commentaires

4 Réponses :


1
votes

Il y a probablement quelques erreurs ponctuelles dans votre code.

Vous pouvez trouver Fonction d'extension chunked utile ici:

fun verifySensor(template: String) {

    template.chunked(20).forEach { subTemplate ->
        writeToService(subTemplate.toByteArray())
    }

    writeToService("VERIFY".toByteArray())

}

Notez que si votre chaîne de modèle contient caractères non-ascii, la sous-chaîne codée de 20 caractères peut être plus longue que 20 octets. Si cela pose un problème pour votre service, vous devez d'abord convertir la chaîne en octets, puis envoyer ces octets en morceaux.


0 commentaires

0
votes

Je pense que cela peut être faux val iterationTimes = template.length / 20 . Par exemple;

20/21 renvoie 1 mais vous devez répéter 2 fois. Alors peut-être que vous pouvez augmenter iterationTimes comme val iterationTimes = template.length / 20 + 1


0 commentaires

1
votes

D'abord , cette division:

for (value in 1 until iterationTimes)

est une division entière, donc si la longueur de la chaîne n'est pas un multiple de 20 alors le résultat sera le partie entière de la division (pour length = 90 le résultat est 4 ) et les itérations calculées laisseront de côté la dernière partie de la chaîne (le reste de la division longueur / 20 ).

Deuxièmement , lorsque vous utilisez jusqu'à pour définir une plage, comme cette boucle:

val iterationTimes = template.length / 20

vous devez savoir que la limite supérieure est exclue.
Ainsi, les itérations s'arrêtent lorsque la valeur atteint iterationTimes - 1 et que vous manquez la dernière itération.


0 commentaires

0
votes

Cela a donc fonctionné pour moi

implementation "com.squareup.okio:okio:2.3.0"

Ici ::

val raw = template.decodeHex().toByteArray()

J'ai utilisé la bibliothèque Okio https://github.com/square/okio pour décoder les chaînes de Hex

fun verifySensor(template: String) {

    val raw = template.decodeHex().toByteArray()


    var index = 0
    while (index < raw.size) {
        val chunkSize: IntRange = if (index + 19 > raw.lastIndex) {
            IntRange(index, raw.lastIndex)
        } else {
            IntRange(index, index + 19)
        }

        val chunkList = raw.slice(chunkSize)

        val chunk = chunkList.toByteArray()
        Thread.sleep(350)
        index += 20

        writeToService(chunk)
    }
    Thread.sleep(350)
    writeToService("VERIFY".toByteArray())
}

J'ai rencontré des problèmes en essayant d'envoyer le bloc d'octets, la plupart des octets n'étant pas envoyés au service. J'ai donc dû mettre le thread en veille pendant 350 millisecondes pour que chaque bloc d'octets soit envoyé complètement.


0 commentaires