Base64 le calcul de la longueur?
Après la lecture de la base64 wiki ...
Je suis à essayer de comprendre comment la formule de travail :
Donné une chaîne d'une longueur de n
, le base64 longueur sera
Qui est : 4*Math.Ceiling(((double)s.Length/3)))
Je sais déjà que base64 longueur doit être %4==0
pour permettre au décodeur de savoir quelle était l'origine de la longueur du texte.
Le nombre maximal de remplissage pour une séquence peut être =
ou ==
.
wiki :Le nombre de sortie octets par octets d'entrée est d'environ 4 /3 (33%
les frais généraux)
Question:
Comment les informations ci-dessus s'installer avec la longueur de sortie ?
Vous devez vous connecter pour publier un commentaire.
Chaque caractère est utilisé pour représenter les 6 bits (
log2(64) = 6
).Donc les 4 caractères sont utilisés pour représenter
4 * 6 = 24 bits = 3 bytes
.Si vous avez besoin
4*(n/3)
caractères pour représentern
octets, et ce doit être arrondi à un multiple de 4.Le nombre de inutilisés rembourrage de caractères résultant de l'arrondi à un multiple de 4 sera évidemment 0, 1, 2 ou 3.
4*(n/3)
permet de dire que vous avez123456
sa longueur est de 6. 6*6=36 bits, qui est de 4,5 octets. à partir de ce pont je ne understnad./3
?4 * n /3
donne unpadded longueur.Et arrondi au plus proche multiple de 4 pour le rembourrage, et que 4 est une puissance de 2 pouvez utiliser les opérations logiques bit à bit.
$(( ((4 * n / 3) + 3) & ~3 ))
4 * n / 3
déjà échoue àn = 1
, un octet est codé à l'aide de deux caractères, et le résultat est clairement un caractère.Pour référence, l'encoder en Base64 de la longueur de la formule suivante:
Comme vous l'avez dit, un encoder en Base64 donné
n
octets de données à produire une chaîne de4n/3
Base64 caractères. Mettre une autre manière, tous les 3 octets de données de 4 Base64 caractères. MODIFIER: UN commentaire souligne à juste titre que mon graphique précédent n'a pas tenu compte pour le rembourrage; la formule correcte estCeiling(4n/3)
.L'article de Wikipédia montre exactement comment la chaîne de caractères ASCII
Man
encodé en Base64 chaîneTWFu
dans son exemple. La chaîne d'entrée est de 3 octets, ou 24 bits, la taille, donc la formule prédit correctement la sortie est de 4 octets (32 bits):TWFu
. Le processus encode tous les 6 bits de données dans l'un des 64 Base64 caractères, de sorte que le 24-bits d'entrée divisée par 6 résultats chez 4 Base64 caractères.Vous demander dans un commentaire ce que la taille de l'encodage
123456
serait. En gardant à l'esprit que chaque chaque caractère de la chaîne est de 1 octet, soit 8 bits, la taille (en supposant ASCII/encodage UTF8), nous sommes d'encodage de 6 octets, ou 48 bits de données. Conformément à l'équation, nous nous attendons à la sortie de la longueur à(6 bytes /3 bytes) * 4 characters = 8 characters
.Mettre
123456
en Base64 codeur créeMTIzNDU2
, qui est de 8 caractères de long, tout comme nous nous y attendions.floor((3 * (length - padding)) / 4)
. Découvrez la suite de résumé.Entiers
En général, nous ne voulons pas utiliser de doubles, parce que nous ne voulons pas utiliser la virgule flottante ops, les erreurs d'arrondi etc. Ils sont tout simplement pas nécessaires.
Pour cela, il est une bonne idée de se rappeler comment effectuer le plafond de la division:
ceil(x /y)
en double peut être écrite comme(x + y - 1) /y
(tout en évitant les nombres négatifs, mais méfiez-vous de débordement).Lisible
Si vous allez pour des raisons de lisibilité, vous pouvez bien sûr également au programme comme ceci (exemple en Java, C vous pouvez utiliser de macro, bien sûr):
Inline
Collier de
Nous savons que nous avons besoin de 4 caractères des blocs à la fois pour chacun des 3 octets (ou moins). Alors la formule devient (pour x = n et y = 3):
ou de façon combinée:
votre compilateur d'optimiser le
3 - 1
, il suffit donc de le laisser comme cela pour maintenir la lisibilité.Unpadded
Moins commun, c'est la unpadded variante, et pour cela nous rappeler que chacun de nous avons besoin d'un personnage pour chaque 6 bits, arrondie:
ou de façon combinée:
on peut cependant encore diviser par deux (si on veut):
Illisible
Dans le cas où vous n'avez pas confiance en votre compilateur de faire la finale des optimisations pour vous (ou si vous voulez prendre vos collègues):
Collier de
Unpadded
Voilà, deux façons logiques de calcul, et nous n'avons pas besoin branches, bit-ops ou modulo ops - à moins que nous voulons vraiment.
Notes:
Je pense que les réponses données manquer le point de la question d'origine, qui est de savoir combien d'espace doit être alloué pour l'ajustement de l'encodage base64 pour une chaîne binaire de longueur n octets.
La réponse est
(floor(n /3) + 1) * 4 + 1
Cela comprend un rembourrage et un caractère de fin null. Vous ne pouvez pas besoin de l'étage d'appel si vous faites l'arithmétique des nombres entiers.
Y compris rembourrage, base64, chaîne nécessite quatre octets pour tous les trois-octet morceau de la chaîne d'origine, y compris toute partielle morceaux. Un ou deux octets supplémentaires à la fin de la chaîne va encore se converti à quatre octets de la chaîne base64 lorsque le remplissage est ajouté. Sauf si vous avez un usage très spécifique, il est préférable d'ajouter le remplissage, généralement égal caractère. J'ai ajouté un octet supplémentaire pour un caractère null en C, car les chaînes ASCII sans ce sont un peu dangereux et vous auriez besoin de transporter de la longueur de la corde séparément.
Voici une fonction pour calculer la taille d'origine d'un encodé en Base 64 fichier comme une Chaîne de caractères dans la base de connaissances:
Me semble que la formule devrait être:
Alors que tout le monde est à débattre de formules algébriques, je préfère suffit d'utiliser BASE64 lui-même à me dire:
525
710
Il semble donc que la formule de 3 octets étant représenté par 4 base64 personnages semble correcte.
Je crois que c'est une réponse exacte si n%3 pas de zéro, non ?
Mathematica version :
Avoir du plaisir
GI
Dans windows - j'ai voulu estimer la taille de mime64 de la taille de la mémoire tampon, mais tous les précis de la formule de calcul n'a pas de travail pour moi - enfin j'ai fini avec la formule approximative comme ceci:
Mine64 chaîne répartition de la taille (approximative)
= (((4 * ((binaire, taille de la mémoire tampon) + 1)) /3) + 1)
Dernière, +1 - il est utilisé pour ascii-zéro - dernier caractère doit allouée pour stocker zéro de fin - mais pourquoi "binaire, taille de la mémoire tampon" est de + 1, je crois qu'il y a quelques mime64 caractère de fin ? Ou peut-être que c'est quelque problème d'alignement.
Simple implementantion en javascript
Si il y a quelqu'un qui s'intéresse à atteindre l' @Pedro Silva solution en JS, j'ai juste porté cette même solution pour elle: