[Résolu] Valeur Binaire, Hexadécimal d'un caractère

iLandesiLandes Membre
février 2016 modifié dans Objective-C, Swift, C, C++ #1

Bonjour,


 


Les week-end pluvieux je passe mon temps sur CodinGame pour améliorer mon swift. Je bug sur un challenge où il faut commencer par définir la valeur binaire d'un caractère. Peut être en passant par sa valeur hexadécimale. Je ne riens trouver à  ce sujet nul par.


 


En gros "C" doit donner "1000011".


 


Merci pour vos pistes.


 


Cordialement


Réponses

  • DrakenDraken Membre
    février 2016 modifié #3

    Plutôt que de l'hexadécimal, tu peux saisir une valeur directement sous forme binaire, avec l'entête 0b :



    let binaire = 0b0100010

    Un exemple tiré de la doc Apple :



    let initialBits: UInt8 = 0b00001111
  • iLandesiLandes Membre
    février 2016 modifié #4

    Merci pour vos réponses, mais cela ne m'aide pas.


     


    Voici sous forme de code ce que je cherche à  faire





    import Foundation

    func charToBin(c:Character) -> String {
    //
    // NE MARCHE QUE POUR C
    //
        let binaire = 34 // Soit en binaire pour C : 0100010
        return String(binaire, radix: 2)
    }

    let c:Character = "C"
    let b = charToBin(c)

    Mais peut-être que la fonction que je cherche à  écrire existe déjà  en swift mais je ne la trouve pas...




  •  


    Plutôt que de l'hexadécimal, tu peux saisir une valeur directement sous forme binaire, avec l'entête 0b :



    let binaire = 0b0100010

    Un exemple tiré de la doc Apple :



    let initialBits: UInt8 = 0b00001111



    Merci mais ce n'est pas ce que je cherche...

  • CéroceCéroce Membre, Modérateur
    février 2016 modifié #6
    Un caractère ne tient pas forcément sur un octet. Y'a-t-il un moyen de créer une chaà®ne en précisant l'encodage ?


  • Parce que comme ça, un caractère tient sur un octet ? C'était peut-être vrai en 1992, mais plus aujourd'hui.

    Saute cet exercice pourri.




     


    Je suis d'accord avec toi. CodinGame propose des challenge à  résoudre dans plusieurs dizaines de langages. Le but ici est d'écrire un convertisseur appelé Chuck Norris ;-)


     


    C'est pour le fun et pour faire travailler la matière grise le but n'est pas de faire une app iOS multilingues qui gère les smiley et tous les caractères du monde.


     


    Juste se creuser la tête. J'arrive au but.


     


    Voici un résumé de l'énoncé :


     



     


    Prenons un exemple simple avec un message constitué d'un seul caractère : C majuscule. C en binaire vaut 1000011 ce qui donne avec la technique de Chuck Norris :


    • 0 0 (la première série composée d'un seul 1)
    • 00 0000 (la deuxième série composée de quatre 0)
    • 0 00 (la troisième série composée de deux 1)

    C vaut donc : 0 0 00 0000 0 00


  • samirsamir Membre
    février 2016 modifié #8

    Je n'ai pas bien saisie le problème de codingGame, mais si tu veux retrouver la valeur binaire de ton caractère :



    var str: String = "c"
    let scalars = str.unicodeScalars
    let unicode = scalars[scalars.startIndex].value

    Ensuite tu transformes cette valeur en binaire.



    let binaryStr = String(unicode, radix: 2)
  • iLandesiLandes Membre
    février 2016 modifié #9

    Voici ma solution.


     


    Je vais pouvoir m'attaquer à  Chuck Norris



    func stringToBinaryString (myString:String) -> String {
        // Array of characters
        let characterArray = [Character](myString.characters)

        // Array of asccii value
        let asciiArray = characterArray.map({String($0).unicodeScalars.first!.value})

        // Array of binary value
        let binaryArray = asciiArray.map ({ String($0, radix: 2)})
        
        // Reduce in a String
        let r = binaryArray.reduce("",combine: {$0 + " " + $1})

        return r
    }


    let r = stringToBinaryString("CC")
  • DrakenDraken Membre
    février 2016 modifié #10

    Une autre solution :



    let c:Character = "C"
    var binaire = ""

    for u:UInt8 in String(c).utf8 {
    binaire = String(u, radix:2)
    }

    print ("Binaire : ", binaire)


  • AliGatorAliGator Membre, Modérateur
    Mais ça n'a aucun sens ce problème. Ca fait quoi si le caractère au lieu d'être "C" c'est "é" ou "à " ? Sans parler tout simplement de " " ou """...
    Un Character est loin d'avoir une seule représentation binaire...

    Le problème est mal posé ou alors il montre la non connaissance du sujet par la personne qui a énoncé le problème. La bonne réponse est "il n'y a pas de réponse universelle, il manque des éléments pour préciser ce que l'on veut obtenir".


  • Mais ça n'a aucun sens ce problème. Ca fait quoi si le caractère au lieu d'être "C" c'est "é" ou "à " ? Sans parler tout simplement de " " ou """...




     


     


    "é", "à ", ... ont une représentation unique en Unicode.


    Elle est surement différente (ou inexistante ) de la representation UTF8, ou UTF16. 


     


    Donc avec le code en haut on obtient l'encodage Unicode qu'on transforme en binaire. 


     


    Les précisions dont tu parles, c'est de préciser si on cherche la representation UTF8, UTF16, ou Unicode ? 


     


    ( je suis entrain de lire un article intéressant pour ceux que ça intéressent et qui ne maitrisent pas trop comme moi :)


    http://kunststube.net/encoding/

  • DrakenDraken Membre
    février 2016 modifié #13


    Mais ça n'a aucun sens ce problème. Ca fait quoi si le caractère au lieu d'être "C" c'est "é" ou "à " ? Sans parler tout simplement de " " ou """...

     




    J'ai regardé la valeur de "é" avec différents codages :


     


    En utf8, c'est deux octets : 195 169 (ma méthode)


    En utf16 : 233 (ma méthode)


    En unicode : 99 (méthode de Samir)


     


    La méthode compliqué de iLandes donne la valeur de l'utf16.


     


    C'est clair qu'il y a comme un problème.

  • Joanna CarterJoanna Carter Membre, Modérateur
    Je me demandais, en dehors d'un exercice, pourquoi devrait-on vouloir le faire ?
  • FKDEVFKDEV Membre
    février 2016 modifié #15

    Les précisions dont tu parles, c'est de préciser si on cherche la representation UTF8, UTF16, ou Unicode ?


    En toute rigueur, il faut indiquer de quel codage on parle.
    Il y a eu une vie avant l'Unicode et ses différents encodages.
    Il existe de nombreux autres codages (http://www.i18nguy.com/unicode/codepages.html) dont le plus célèbre est le codage selon la table ASCII.

    En ce qui concerne le caractère 'C', on ne peut pas beaucoup se tromper car il n'y a pas dû avoir beaucoup de variantes dans la valeur attribuée à  cette lettre.

    Mais pour les caractères spéciaux qui n'étaient pas dans la table ASCII initiale (de 0 à  127), il y a eu pas mal d'alternatives car chacun a fait son propre mapping.

    Par exemple, pour 'é':

    Windows CP 1252: 0xe9 (Windows)
    Mac Roman: 0x8e (Mac OS)
    IBM CP 850: 0x82 (codepage qu'on trouve par défaut dans beaucoup de LCD non graphique)
  • FKDEVFKDEV Membre
    février 2016 modifié #16
    Cet exercice est confus, autant faire deux exercices:
    -un sur l'encodage des caractères et
    -un autre sur la représentation des entiers en hexadécimale, décimale, octale, binaire et base 1.

    Sachant que si on veut vraiment être pointilleux, il faudrait indiquer quel système de numération il faut utiliser quand on demande de répresenter un nombre dans une base donnée.

    Déjà  en base 1, il y a plusieurs manière de faire: https://fr.wikipedia.org/wiki/Système_unaire.

    Pour résumer:
    Un caractère (e.g. 'C') peut-être codée par un nombre selon une méthode d'encodage,
    ce nombre peut lui-même être écrit dans une base donnée (base 1, base 10, base 16),
    avec un système de symboles donné (chiffres romain, chiffres arabe pour la base 10).


    J'imagine l'entretien d'embauche.
    L'examinateur: "Monsieur, veuillez m'écrire la représentation binaire de 'C'".
    Le candidat un peu trop pointilleux: "Si j'ai bien compris, vous voulez que j'écrive ce caractère en base 2. Pouvez-vous m'indiquer la table d'encodage et le système numéraire à  utiliser s'il vous plait ?"
    -euh... merci, ça ira, on vous rappellera..."
  • iLandesiLandes Membre
    février 2016 modifié #17

    Je pense que vous ne connaissez pas codingame.


     


    Le but est de faire tourner un petit morceaux de code qui est vérifier en ligne. Il ne s'agit pas de faire une application, juste ce creuser les méninges. Personnellement cela m'aide de façon ludique à  perfectionner mon swift.


     


    Arrêter de vous emballer avec vos histoires d'encodage, cela n'a pas grand chose a voir avec la discussion.


     


    Les challenges sont ludiques et n'ont pas vocation a fonctionner ailleurs que sur la plateforme de codingame. Allez y faire un tour et vous comprendrez mieux.


     


    Personnellement cela m'a aider a appréhender des notions comme map et reduce.


     


    Ils ont pas mal de challenges animés ou il faut écrire par exemple un petit code pour faire atterrir une fusée en douceur ou piloter une moto en adaptant sa vitesse pour sauter des obstacles. 


     


    Je le redis, le but est de travailler sur des données définies dans le cahier des charges et d'offrir un traitement qui doit passer les tests de leur simulateur. On peut aussi voir comment d'autres ont réussit le même challenge.


     


    J'avoue cela n'a rien à  voir avec le développement iOS ou MacOS cela sert juste à  approfondir un langage. Les exercices se résolvent en une heure ou deux maximum. Cela occupe les week-end pluvieux. Pour ceux que ça intéresse je suis inscrit sur cette plateforme avec le même pseudo qu'ici.


     


    Dernière précision je n'ai aucun lien avec ce site.


     


    Pour les curieux, voici l'énoncer complet :


     


     


     






     Objectif

    Le binaire avec des 0 et des 1 c'est bien. Mais le binaire avec que des 0, ou presque, c'est encore mieux. A l'origine, c'est un concept inventé par Chuck Norris pour envoyer des messages dits unaires.


    Ecrivez un programme qui, à  partir d'un message en entrée, affiche le message codé façon Chuck Norris en sortie.






     Règles


    Voici le principe d'encodage :


    • Le message en entrée est constitué de caractères ASCII (7 bits)
    • Le message encodé en sortie est constitué de blocs de 0
    • Un bloc est séparé d'un autre bloc par un espace
    • Deux blocs consécutifs servent à  produir une série de bits de même valeur (que des 1 ou que des 0) :
      - Premier bloc : il vaut toujours 0 ou 00. S'il vaut 0 la série contient des 1, sinon elle contient des 0

      - Deuxième bloc : le nombre de 0 dans ce bloc correspond au nombre de bits dans la série






     Exemple

    Prenons un exemple simple avec un message constitué d'un seul caractère : C majuscule. C en binaire vaut 1000011 ce qui donne avec la technique de Chuck Norris :


    • 0 0 (la première série composée d'un seul 1)
    • 00 0000 (la deuxième série composée de quatre 0)
    • 0 00 (la troisième série composée de deux 1)

    C vaut donc : 0 0 00 0000 0 00


     

    Deuxième exemple, nous voulons encoder le message CC (soit les 14 bits 10000111000011) :


    • 0 0 (un seul 1)
    • 00 0000 (quatre 0)
    • 0 000 (trois 1)
    • 00 0000 (quatre 0)
    • 0 00 (deux 1)

    CC vaut donc : 0 0 00 0000 0 000 00 0000 0 00






     Entrées du jeu

    Entrée

    Ligne 1 : le message composé de N caractères ASCII (sans retour chariot)



    Sortie

    Le message encodé



    Contraintes

    0 < N < 100



    Exemple




    Entrée

    C


    Sortie

    0 0 00 0000 0 00





  • Finalement, il est assez précis cet énoncé.
  • DrakenDraken Membre
    février 2016 modifié #19


     


    Ils ont pas mal de challenges animés ou il faut écrire par exemple un petit code pour faire atterrir une fusée en douceur ou piloter une moto en adaptant sa vitesse pour sauter des obstacles. 


     




    Quelle horreur l'atterrissage de la fusée. J'ai tenté de le faire dans une mini-convention organisée par codingame. La fusée faisait des trucs bien louche sur l'écran, avant de s'écraser en beauté.


  • En lisant ton sujet j'ai découvert ce site ! je m'y suis inscrit et effectivement c'est vraiment bien fait !

  • A l'ancienne :


    let input = String("CC")
    var result:String = ""
    var currentBitValue:Int = -1
    var currentCounter = 0;
    for utf8Code in input.utf8 {
    for indexCode in 0..<7 {
    let bitValue = (Int(utf8Code) >> (6-indexCode))&1
    if bitValue == currentBitValue {
    currentCounter += 1
    } else {
    if (currentBitValue == 0) {
    result = result + "00 "
    }
    else if (currentBitValue == 1) {
    result = result + "0 "
    }

    if currentCounter > 0 {
    result += String(count:currentCounter, repeatedValue: Character("0"))
    result += " "
    }
    currentCounter = 1
    currentBitValue = bitValue
    }
    }
    }

    if (currentBitValue == 0) {
    result = result + "00 "
    }
    else if (currentBitValue == 1) {
    result = result + "0 "
    }

    result += String(count:currentCounter, repeatedValue: Character("0"))

    print(result)
  • On voyant ton code, on se rend compte mieux de l'importance des fonctions map, flatMap, reduce et consoeurs :)




  • A l'ancienne :

     



    let input = String("CC")
    var result:String = ""
    var currentBitValue:Int = -1
    var currentCounter = 0;
    for utf8Code in input.utf8 {
    for indexCode in 0..<7 {
    let bitValue = (Int(utf8Code) >> (6-indexCode))&1
    if bitValue == currentBitValue {
    currentCounter += 1
    } else {
    if (currentBitValue == 0) {
    result = result + "00 "
    }
    else if (currentBitValue == 1) {
    result = result + "0 "
    }

    if currentCounter > 0 {
    result += String(count:currentCounter, repeatedValue: Character("0"))
    result += " "
    }
    currentCounter = 1
    currentBitValue = bitValue
    }
    }
    }

    if (currentBitValue == 0) {
    result = result + "00 "
    }
    else if (currentBitValue == 1) {
    result = result + "0 "
    }

    result += String(count:currentCounter, repeatedValue: Character("0"))

    print(result)



     A l'ancienne ? Où sont les chèvres et les tablettes d'argiles ?

  • AliGatorAliGator Membre, Modérateur

    "é", "à ", ... ont une représentation unique en Unicode.
    Elle est surement différente (ou inexistante ) de la representation UTF8, ou UTF16.

    Faux.

    "é" peut se représenter en Unicode :
    - Soit avec sa forme NFC (forme pré-composée), via le codepoint U+00e9
    - Soit avec sa forme NFD (forme décomposée), via le codepoint U+0065 (caractère "e") suivi du codepoint U+0301 (diacritique accent aigu)

    Voir : https://en.wikipedia.org/wiki/Unicode_equivalence

    Ensuite, une fois que tu as choisi une des 2 formes Unicodes du caractère, il y a effectivement en plus l'encodage de texte choisi (UTF8 / UTF16LE / UTF16BE / UTF32 / ...) qui joue également, mais ça c'est la stérilisation des codepoints unicode sur disque ou en mémoire, c'est un encodage, une représentation sérialisée des données. Donc c'est encore une autre étape.

    Il y a donc plusieurs niveaux de transformations dans Unicode
    * 1 Caractère --> plusieurs Scalars (= 1 CodePoint ou une suite de CodePoints) selon la forme NFC, NFD, NFKD, NFKC
    * 1 ScalarView (suite de CodePoints) --> plusieurs stérilisations possibles (UTF8, UTF16, UTF32...)



    Tenez, d'ailleurs pour vous montrer à  quel point Unicode peut aller loin avec les combining marks, ceci est un texte tout à  fait valable en Unicode et qui se représente très bien comme étant une suite de CodePoints et de Combining Marks :




    oe²Ì¸Ì»Ì¤Ì¹Ì¯Í‰Ì¼Ì…̀̊̂̚͝n̢̹̲̹̤͛͗̆̓͒̕͢͢à­ÌžÌ«Ì–̼̀̿̂̚͜c̵̡̤̰̠̦͓̟̐̔͑͐̇̄̆͊ơ̸̢̗̘͇͇̪̔̅̂̀́̚͜ͅd̹̟̻̰̬̗̫̤̈̆͌̄̕͞͡ě̜̩͈͈̜̄̊̏͌͆ ç̶͉̮̟͚̦͒̅̚͟͠͞ă̛͓͙͓̪̠͍̳̌̓̀̈̈̀͡ d̬̟̪͎̞̯̭͕͐̉͂̌͞ȩ̨̛̦͇̻́̀̍̑́̒͟͜͡͝b̷̝̥̹̮͙̭̔͊͆̑̒͌͐̕ͅà²Ì–̮̯̼̠̑̉͋̕à®Ì¶Ì¢Ì¡Ì›ÌºÍ”͕̥͚̻̉́̏̒͗̔t̶͈̲̬͇̜͑̃̀̑̇̀e̢̻̫̝̣̬͛̂̎̀̀̔̀͊́͠
  • FKDEVFKDEV Membre
    février 2016 modifié #25


    On voyant ton code, on se rend compte mieux de l'importance des fonctions map, flatMap, reduce et consoeurs  :)




     


     


    J'ai toujours eu un peu de mal avec ces concepts, je les utilise uniquement pour les cas très simples:


    conversions pour map et aggregation (somme) pour reduce.


     


    Si c'est plus compliqué que cela, c'est à  mon avis une bêtise de les utiliser.


     


    Mais, bon, dans ce cas précis, je suis intéressé pour voir ce que cela donnerait car je n'arrive pas à  imaginer facilement comment faire.


     


    C'est surement une question d'habitude, mais je ne vois pas trop l'intérêt de se compliquer la vie pour les utiliser quand ces fonctions n'apportent pas une simplification d'écriture évidente.


     


    Après, il y a le fait que ces fonctions permettent un traitement en parallèle de différente partie d'un tableau, mais je ne sais pas si en pratique c'est fait par le compilateur swift.


     


    En plus, en swift, on se retrouve vite avec $0 et des $1 qui ne facilitent pas la compréhension.


Connectez-vous ou Inscrivez-vous pour répondre.