6
votes

Convertir une chaîne hexadécimale de 128 bits en chaîne de base-36

J'ai un nombre de 128 bits à Hexadecimal stocké dans une chaîne (de MD5, la sécurité n'est pas une préoccupation ici) que je souhaite convertir en une chaîne de base-36. S'il s'agissait d'un numéro de 64 bits ou moins, je le convertirais à un entier 64 bits, utilisez un algorithme que j'ai trouvé pour convertir des entiers en cordes de base-36, mais ce nombre est trop grand pour cela, donc je suis un peu à une perte pour comment aborder cela. Toutes les directives seraient appréciées.

Edit: Après que Roland Illig a souligné le tracas de dire 0 / o et 1 / l sur le téléphone et ne gagnant pas beaucoup de densité de données sur Hex, je pense que je peux finir par rester avec hex. Je suis toujours curieux si s'il y a un moyen relativement simple de convertir une chaîne hexagonale de longueur arbitraire en une chaîne de base-36.

c++

0 commentaires

4 Réponses :


6
votes

Un codage de base-36 nécessite 6 bits pour stocker chaque jeton. Identique à la base 64 mais n'utilisant pas 28 des jetons disponibles. Résolution 36 ^ N> = 2 ^ 128 Connectements N> = LOG (2 ^ 128) / Journal (36) ou 25 jetons pour encoder la valeur.

Un codage de base-64 nécessite également 6 bits, toutes les valeurs de jeton possibles sont utilisées. Résolution 64 ^ N> = 2 ^ 128 Données N> = LOG (2 ^ 128) / Journal (64) ou 22 jetons pour coder la valeur.

Calculer le codage de base-36 nécessite de diviser par des pouvoirs de 36. Pas de raccourcis faciles, vous avez besoin d'un algorithme de division pouvant fonctionner avec des valeurs de 128 bits. Le codage de base-64 est beaucoup plus facile à calculer car il s'agit d'une puissance de 2. Il suffit de prendre 6 bits à la fois et de passer par 6, au total 22 fois pour consommer tous les 128 bits.

Pourquoi voulez-vous utiliser BASE-36? Les codeurs de base-64 sont standard. Si vous avez vraiment une contrainte sur l'espace de jeton (vous ne devriez pas, ASCII RimeZ), utilisez au moins un codage de base-32. Ou une puissance de 2, base-16 est hexagone.


7 commentaires

@eco: Si une restriction technique vous limite à 36 caractères, vous voudrez peut-être utiliser la base-32 à la place. Vous devrez utiliser 26 "chiffres" au lieu de 25, mais vous pouvez utiliser BitShifting.


La raison de la base-36 est donc donc facilement lisible par téléphone aux humains. Base-36 permettrait d'utiliser tous les chiffres et alphabet qui rendraient beaucoup plus courte que d'utiliser Hexadecimal.


Base-36 code un peu plus de 5 bits par chiffre, ce qui n'est pas beaucoup plus que les 4 bits que vous obtenez à l'aide de Hex. Le risque que vous prenez est que les gens confondent 0 avec O et 1 avec I. Je ne pense pas que cela vaut l'effort. Vous devriez plutôt utiliser les dix chiffres décimaux et les imprimer en groupes de quatre.


@Roland c'est un bon point. Je préfère ne pas traiter avec 0 / o et 1 / l et la convertir à une base inhabituellement représentée (n ° O ou L), 34 limiterait la densité à ne pas en valoir la peine. Je peux juste rester avec hex je suppose.


Yuck, depuis quand les gens ont-ils déjà pu traiter avec 22 jetons? Un ordinateur ne dérange pas la différence entre un 1 et un I ou un L. AT & T s'est avéré il y a longtemps que la capacité humaine est de 7 jetons, 10 si vous le poussez. Le nombre de chiffres vous composez sur un téléphone pour parler à quelqu'un. Il y a un niveau de pragmatisme qui doit grincer dans cette question. Les hachages sont pour les machines, pas les gens.


J'avais réellement prévu de le tronquer à 16 (4 groupes de 4). Je n'ai pas vraiment besoin de 16 et j'envisagerais de la supporter encore plus loin si cela n'était pas pour le fait que cela doit être uniforme avec un autre système que nous avons déjà en place qui utilise 16 ans. Penser à cela me fait comprendre Encore plus de sorte que Hex devrait suffire.


En ce qui concerne I / 1 et O / 0, il suffit d'omettre les quatre et vous avez 32 caractères pour faire un codage de base bien rangé-32 sans ces points de douleur.



1
votes

Si la seule chose qui manque est la prise en charge des entiers non signés de 128 bits, voici la solution pour vous: xxx

à l'aide de cette fonction, vous pouvez calculer plusieurs fois le résultat MOD-36, qui vous conduit au nombre codé comme base-36.


0 commentaires

1
votes

Si vous utilisez C ++ avec .NET 4, vous pouvez toujours utiliser System.numerics.biginteger classe. Vous pouvez essayer d'appeler l'une des substitutions de Tostring pour vous permettre de baser 36.

Regardez alternativement l'une des nombreuses bibliothèques de grandes entières inteer. Bibliothèque de Big Integer C ++ de Matt McCutchen Bien que vous puissiez avoir à regarder dans le profondeurs des classes pour utiliser une base personnalisée telle que 36.


0 commentaires

1
votes

Deux choses:
1. Ce n'est vraiment pas si difficile de diviser une chaîne d'octets de 36. Mais si vous ne pouvez pas être dérangé pour mettre en œuvre cela, vous pouvez utiliser le codage de base-32, qui aurait besoin de 26 octets au lieu de 25.
2. Si vous souhaitez pouvoir lire le résultat par téléphone aux humains, vous devez absolument ajouter une simple somme de contrôle à votre chaîne, qui coûtera un ou deux octets, mais vous économiserez une énorme quantité de «chinois» tracas de Clients durement auditifs.


1 commentaires

Hmm, je viens de trouver ce Crockford.com/wrmg/base32.html qui serait Apacez certains des problèmes discutés sur une autre réponse. Je n'avais pas considéré comme une somme de contrôle. Je vais regarder dans ça. Merci.