J'ai un nombre de 128 bits en hexadécimal stocké dans une chaîne (de md5, la sécurité n'est pas un problème ici) que je voudrais convertir en base- 36 cordes. Si c'était un nombre de 64 bits ou moins, je le convertirais en un entier de 64 bits, puis utiliser un algorithme que j'ai trouvé pour convertir des entiers en chaînes de base 36, mais ce nombre est trop grand pour cela, donc je suis en quelque sorte une perte pour la façon d'aborder cela. Toute orientation serait appréciée. Edit: Après que Roland Illig a souligné les tracas de dire 0/O et 1/l sur le téléphone et ne pas gagner beaucoup de densité de données sur hex, je pense que je peux finir par rester avec hex. Je suis toujours curieux de savoir s'il existe un moyen relativement simple de convertir une chaîne hexadécimale de longueur arbitraire en une chaîne de base 36.Convertir une chaîne hexadécimale de 128 bits en chaîne base-36
Répondre
Un codage en base 36 nécessite 6 bits pour stocker chaque jeton. Identique à base 64 mais n'utilisant pas 28 des jetons disponibles. La résolution de 36^n> = 2^128 donne n> = log (2^128)/log (36) ou 25 jetons pour encoder la valeur.
Un codage en base 64 nécessite également 6 bits, toutes les valeurs de jeton possibles sont utilisées. La résolution 64^n> = 2^128 donne n> = log (2^128)/log (64) ou 22 jetons pour encoder la valeur.
Le calcul de l'encodage en base 36 nécessite une division par des puissances de 36. Pas de raccourcis faciles, vous avez besoin d'un algorithme de division qui peut fonctionner avec des valeurs de 128 bits. L'encodage base-64 est beaucoup plus facile à calculer car il est une puissance de 2. Prenez 6 bits à la fois et passez de 6, au total 22 fois pour consommer tous les 128 bits.
Pourquoi voulez-vous utiliser base-36? Les codeurs Base-64 sont standard. Si vous avez vraiment une contrainte sur l'espace de jeton (vous ne devriez pas, rulez ASCII) alors utilisez au moins un encodage base-32. Ou toute puissance de 2, la base 16 est hex.
Si la seule chose qui manque est le support de 128 bits entiers non signés, voici la solution pour vous:
#include <stdio.h>
#include <inttypes.h>
typedef struct {
uint32_t v3, v2, v1, v0;
} uint128;
static void
uint128_divmod(uint128 *out_div, uint32_t *out_mod, const uint128 *in_num, uint32_t in_den)
{
uint64_t x = 0;
x = (x << 32) + in_num->v3;
out_div->v3 = x/in_den;
x %= in_den;
x = (x << 32) + in_num->v2;
out_div->v2 = x/in_den;
x %= in_den;
x = (x << 32) + in_num->v1;
out_div->v1 = x/in_den;
x %= in_den;
x = (x << 32) + in_num->v0;
out_div->v0 = x/in_den;
x %= in_den;
*out_mod = x;
}
int
main(void)
{
uint128 x = { 0x12345678, 0x12345678, 0x12345678, 0x12345678 };
uint128 result;
uint32_t mod;
uint128_divmod(&result, &mod, &x, 16);
fprintf(stdout, "%08"PRIx32" %08"PRIx32" %08"PRIx32" %08"PRIx32" rest %08"PRIx32"\n", result.v3, result.v2, result.v1, result.v0, mod);
return 0;
}
Cette fonction vous pouvez calculer à plusieurs reprises le mod-36 résultat, ce qui vous conduit au nombre codé comme base-36.
Si vous utilisez C++ avec .NET 4, vous pouvez toujours utiliser la classe System.Numerics.BigInteger. Vous pouvez essayer d'appeler l'une des substitutions toString pour accéder à la base 36.
Vous pouvez également consulter l'une des nombreuses bibliothèques Big Integer, par exemple. Matt McCutchen's C++ Big Integer Library bien que vous pourriez avoir à regarder dans le depths of the classes d'utiliser une base personnalisée telle que 36.
Deux choses:
1. Il est vraiment pas difficile de diviser une chaîne d'octets par 36. Mais si vous le pouvez » Pour être implémenté, vous pouvez utiliser l'encodage base-32, qui aurait besoin de 26 octets au lieu de 25.
2. Si vous voulez pouvoir lire le résultat par téléphone pour les humains, vous devez absolument ajouter un simple Somme de contrôle à votre chaîne, ce qui coûtera un ou deux octets, mais vous permettra d'économiser une énorme quantité de tracas «chuchotements chinois» des clients malentendants.
Hmm, je viens de trouver ce http://www.crockford.com/wrmg/base32.html qui soulagerait certains des problèmes discutés sur une autre réponse. Je n'avais pas considéré une somme de contrôle. Je vais regarder dans ça. Merci. – eco
- 1. convertir une chaîne hexadécimale en un NSData
- 2. Convertir une chaîne hexadécimale en données
- 3. Comment convertir une chaîne hexadécimale en entier signé?
- 4. Convertir la chaîne hexadécimale en longue
- 5. Comment générer une chaîne longue de 128 bits?
- 6. En C#, Comment convertir une chaîne hexadécimale en int?
- 7. Comment convertir une chaîne hexadécimale en entier en Python?
- 8. Conversion d'une chaîne hexadécimale en unicode
- 9. convertir la chaîne de caractères hexadécimale en entier en Java
- 10. Comment convertir une chaîne de valeurs hexadécimales en chaîne?
- 11. Convertir le tableau de 0 et 1 en base36 string
- 12. Décodage chaîne hexadécimale en javascript
- 13. convertir un nombre à 10 chiffres en chaîne hexadécimale
- 14. Comment convertir une représentation binaire d'une chaîne en une chaîne?
- 15. BuiltIn fonction de convertir de chaîne hexadécimale à octet
- 16. asp.net Convertir une chaîne CSV en chaîne []
- 17. Chaîne hexadécimale à caractère?
- 18. Java convertir une chaîne HEX en BigInt
- 19. Quelle est la meilleure façon de convertir une chaîne hexadécimale en un tableau d'octets (.NET)?
- 20. Conversion d'un nombre entier en une chaîne hexadécimale dans Ruby
- 21. Comment convertir une chaîne d'octets en Nombre?
- 22. Comment convertir une chaîne de bits à tableau d'octets
- 23. Python: conversion de chaîne binaire/hexadécimale?
- 24. convertir une chaîne en classe
- 25. Convertir une chaîne en .net
- 26. Convertir une chaîne en streaming
- 27. Convertir une chaîne en variable
- 28. Convertir une chaîne en CLLocationCoordinate2D
- 29. Convertir une chaîne en Uri
- 30. Convertir une chaîne avec une représentation hexadécimale d'un double IEEE-754 en variable numérique JavaScript
@eco: S'il existe une restriction technique vous limitant à 36 caractères, vous pouvez utiliser Base-32 à la place. Vous devrez utiliser 26 "chiffres" au lieu de 25, mais vous pouvez utiliser le "bitshifting". – dan04
La raison de base-36 est ainsi il est facilement lisible par téléphone pour les humains. Base-36 me laisserait utiliser tous les chiffres et l'alphabet qui le rendraient beaucoup plus court que l'utilisation d'un hexadécimal. – eco
base-36 encode un peu plus de 5 bits par chiffre, ce qui n'est pas beaucoup plus que les 4 bits que vous obtenez en utilisant hex. Le risque que vous prenez est que les gens confondent 0 avec O et 1 avec I. Je ne pense pas que cela en vaille la peine.Vous devriez plutôt utiliser seulement les dix chiffres décimaux et les imprimer en groupes de quatre. –