Ceci et cela à propos de Base64 (Java)

J'ai eu l'occasion d'incorporer des données d'image dans JSON et encoder / décoder en base64, donc j'enregistrerai ce que j'ai vérifié sous forme de mémorandum.

Qu'est-ce que Base64

Je vais citer cet article car il a été expliqué de manière facile à comprendre. https://qiita.com/PlanetMeron/items/2905e2d0aa7fe46a36d4 L'algorithme de conversion Base64 est soigneusement décrit d'une manière facile à comprendre pour votre référence.

Tout simplement ・ A-z (26 caractères) ・ A-Z (26 caractères) ・ 0-9 (10 caractères) ・ + ・ / ・ = (Utilisé comme caractère de remplissage jusqu'à la fin pour aligner la longueur des données) Il semble que ce soit une méthode d'encodage exprimée avec un total de 65 caractères. * Le dernier "=" est une expression de 64 caractères si le remplissage n'est pas requis.

Les données binaires, etc. peuvent être converties en chaînes de 64 (ou 65) caractères afin que les caractères spéciaux ne soient pas inclus dans JSON et que les données puissent être envoyées et reçues en toute sécurité. Puisqu'il n'est exprimé qu'avec 64 (ou 65) types de caractères, c'est aussi une caractéristique que la quantité de données augmente d'environ 1,3 fois (133%).

Lorsque le codage Base64 est utilisé comme format MIME du courrier électronique, un code de saut de ligne (CRLF) est entré tous les 76 caractères selon la norme MIME. En incluant ces 2 octets, la quantité de données est d'environ 137%.

Les formats Base64 sont classés dans les trois modèles suivants.

1. Base64 de base

gu2CoIKigqSCpoKogqmCq4Ktgq+CsYKzgrWCt4K5gruCvYK/gsKCxILGgsiCyYLKgsuCzILNgtCC04LWgtmC3ILdgt6C34LggqCCoA==

・ Les 2 derniers caractères multiples de 4 sont des caractères de remplissage "=" ・ Inclut les symboles +, / (* Si cela est utilisé dans une URL, il sera soumis à un encodage en pourcentage)

2. Base64 avec code de saut de ligne tous les 76 caractères de la norme MIME

gu2CoIKigqSCpoKogqmCq4Ktgq+CsYKzgrWCt4K5gruCvYK/gsKCxILGgsiCyYLKgsuCzILNgtCC
04LWgtmC3ILdgt6C34LggqCCoA==

・ Les 2 derniers caractères multiples de 4 sont des caractères de remplissage "=" ・ Inclut les symboles +, / (* Si cela est utilisé dans une URL, il sera soumis à un encodage en pourcentage)

3. URL-Safe Base64

gu2CoIKigqSCpoKogqmCq4Ktgq-CsYKzgrWCt4K5gruCvYK_gsKCxILGgsiCyYLKgsuCzILNgtCC04LWgtmC3ILdgt6C34LggqCCoA

Les symboles non sécurisés -URL ont été convertis. Supprimer "+" → "-", "/" → "_", "="

Utiliser des applications

Comment utiliser avec Java7,8 ~

Java8~ Depuis Java8 ou version ultérieure, le standard JDK fournit un utilitaire de java.util.Base64, il semble donc bon de l'utiliser. Java 8 ou version ultérieure n'a pas été vérifié sur la machine réelle. Il s'agit d'un exemple de code très simple et facile à comprendre, il a donc été utile. https://gist.github.com/komiya-atsushi/d878e6e4bf9ba6dae8fa

Java7 Pour gérer Base64 avec Java7 ...

--Utiliser le codec Apache Commons --Utilisez javax.mail (en utilisant MimeUtility de JavaMail) --Utilisation de Base64Util de Seasar2 --Faire votre propre

Etc. Cette fois, j'aimerais utiliser les deux premiers "Apache Commons Codec" et "javax.mail" que j'avais sous la main pour effectuer l'encodage / décodage Base64. L'implémentation ici implémente un exemple qui encode / décode les données binaires (byte []) dans une chaîne Base64 (String).

Apache Commons Codec Version: Validé avec 1.11.

Encodage Base64 de base

public static String encodeBase64(byte[] data) {
	return Base64.encodeBase64String(data);
}

Base64 # encodeBase64String``` est utilisé.

Encodage Base64 avec code de saut de ligne tous les 76 caractères de la norme MIME

public static String encodeBase64Chunked(byte[] data) {
	byte[] encoded = Base64.encodeBase64Chunked(data);
	return new String(encoded);
}

⇒ J'utilise Base64 # encodeBase64Chunked```. Une interface pour l'attribution des codes de saut de ligne a été préparée.

Encodage URL-Safe Base64

public static String encodeBase64URLSafe(byte[] data) {
	return Base64.encodeBase64URLSafeString(data);
}

Base64 # encodeBase64URLSafeString``` est utilisé. Il y avait une interface dédiée pour URL-Safe.

Décoder

public static byte[] decodeBase64(String data) {
	return Base64.decodeBase64(data);
}

⇒ Il semble que le décodage puisse être effectué de manière uniforme avec cela.

javax.mail Version: Vérifié avec 1.4.6

Encodage Base64 de base

private static String trimCRLF(ByteArrayOutputStream encodedCRLF) {
	byte inputArray[] = encodedCRLF.toByteArray();
	byte outputArray[] = new byte[encodedCRLF.size()];

	// CR(0x0d)、LF(0x0a)Ignorez la partie et copiez-la dans le tableau de sortie
	int n = 0;
	for (int i = 0; i < encodedCRLF.size() - 1; i++) {
		if (inputArray[i] == 0x0d) {// CR
			if (inputArray[i + 1] == 0x0a) {// LF
				i++;
				continue;
			}
		}
		outputArray[n] = inputArray[i];
		n++;
	}
	return new String(outputArray, 0, n);
}

public static String encodeBase64(byte[] data) {
	try (ByteArrayOutputStream encodedChunked = new ByteArrayOutputStream()) {
		try (OutputStream os = MimeUtility.encode(encodedChunked, "base64")) {
			os.write(data);
			os.flush();
		}
		//Supprimer les caractères de saut de ligne
		String encodedStr = trimCRLF(encodedChunked);
		return encodedStr;

	} catch (IOException e) {
		e.printStackTrace();
		return "Bad Encryption";
	} catch (MessagingException e) {
		e.printStackTrace();
		return "Bad Encryption";
	}
}

⇒ Dans MimeUtility, il semble que vous puissiez encoder avec MimeUtility.encode, Par défaut, il est dans un format basé sur MIME qui inclut des sauts de ligne. Par conséquent, le code de saut de ligne est supprimé pour éliminer les sauts de ligne.

Encodage Base64 avec code de saut de ligne tous les 76 caractères de la norme MIME

public static String encodeBase64Chunked(byte[] data) {
	try (ByteArrayOutputStream encodedChunked = new ByteArrayOutputStream()) {
		try (OutputStream os = MimeUtility.encode(encodedChunked, "base64")) {
			os.write(data);
			os.flush();
		}
		return encodedChunked.toString();

	} catch (IOException e) {
		e.printStackTrace();
		return "Bad Encryption";
	} catch (MessagingException e) {
		e.printStackTrace();
		return "Bad Encryption";
	}
}

⇒ J'utilise MimeUtility.encode.

Encodage URL-Safe Base64

private static String urlSafeEncode(ByteArrayOutputStream encodedCRLF) {
	byte inputArray[] = encodedCRLF.toByteArray();
	byte outputArray[] = new byte[encodedCRLF.size()];

	// CR(0x0d)、LF(0x0a)Ignorez la partie et copiez-la dans le tableau de sortie
	int n = 0;
	for (int i = 0; i < encodedCRLF.size() - 1; i++) {
		if (inputArray[i] == 0x0d) {// CR
			if (inputArray[i + 1] == 0x0a) {// LF
				i++;
				continue;
			}
		}

		// URL-Convertir en sécurité
		if (inputArray[i] == 0x2b) {// 「+」
			outputArray[n] = 0x2d;// 「-」
		}
		else if (inputArray[i] == 0x2f) {// 「/」
			outputArray[n] = 0x5f;// 「_」
		}
		else if (inputArray[i] == 0x3d) {// 「=」
			continue;
		}
		else {
			outputArray[n] = inputArray[i];
		}
		n++;
	}
	return new String(outputArray, 0, n);
}

public static String encodeBase64URLSafe(byte[] data) {
	try (ByteArrayOutputStream encodedChunked = new ByteArrayOutputStream()) {
		try (OutputStream os = MimeUtility.encode(encodedChunked, "base64")) {
			os.write(data);
			os.flush();
		}
		//URL avec le caractère de saut de ligne supprimé-Rendez-le sûr
		String encodedURLSafe = urlSafeEncode(encodedChunked);
		return encodedURLSafe;

	} catch (IOException e) {
		e.printStackTrace();
		return "Bad Encryption";
	} catch (MessagingException e) {
		e.printStackTrace();
		return "Bad Encryption";
	}

⇒ Afin de rendre URL-Safe, les symboles "+", "/" et "=" sont convertis en plus de la suppression du code de saut de ligne. C'est très long. ..

Décoder

public static byte[] decodeBase64(String data) {
	byte[] urlsafe = data.getBytes();
	int mod = urlsafe.length % 4;
	byte[] nosafe = new byte[urlsafe.length + mod];
	for (int i = 0; i < urlsafe.length; i++) {
		if (urlsafe[i] == 0x2d) {// 「-」
			nosafe[i] = 0x2b;// 「+」
		}
		else if (urlsafe[i] == 0x5f) {// 「_」
			nosafe[i] = 0x2f;// 「/」
		}
		else {
			nosafe[i] = urlsafe[i];
		}
	}
	//Ceux qui sont inférieurs à un multiple de la longueur fixe 4=Rembourrage avec
	for (int i = urlsafe.length + mod - 1; i >= urlsafe.length; i--) {
		nosafe[i] = 0x3d;// 「=」
	}

	ByteArrayInputStream from = new ByteArrayInputStream(nosafe);
	try (InputStream is = MimeUtility.decode(from, "base64"); ByteArrayOutputStream to = new ByteArrayOutputStream()) {
		byte[] buf = new byte[8192];
		int readCnt;
		while ((readCnt = is.read(buf)) != -1) {
			to.write(buf, 0, readCnt);
		}
		to.flush();
		return to.toByteArray();

	} catch (MessagingException | IOException e) {
		e.printStackTrace();
		return "Bad Decryption".getBytes();
	}
}

⇒ C'est forcé. .. Dans le processus de décodage, il est reconverti en URL-UnSafe en supposant que la chaîne de caractères convertie sera entrée dans URL-Safe. Après le remplissage avec "=" pour faire correspondre le nombre de chiffres à un multiple de 4, MimeUtility.decode est utilisé pour le décodage. Je ne pense pas que j'écris habituellement ce genre de code.

Résumé

--Il existe trois types principaux de Base64: "format de base", "format standard MIME avec code de saut de ligne" et "format converti URL-Safe".

c'est tout.

Recommended Posts

Ceci et cela à propos de Base64 (Java)
Encodeur Base64 ceci et cela
[À propos de JDBC qui connecte Java et SQL]
[Rails] strftime ceci et cela
À propos du package Java et de l'importation
Certificat électronique ceci et cela
[Java] Téléchargez une image et convertissez-la en Base64
Ceci et cela pour éditer ini en Java. : inieditor-java
À propos des méthodes Java statiques et non statiques
À propos de Biocontainers fastqc et Java
[Java débutant] À propos de l'abstraction et de l'interface
Ceci et cela de JDK
À propos de ça ()
A propos des types primitifs et des types de référence Java
Ceci et cela du contrôle exclusif
Ceci et cela de Swift Corner Radius
À propos de l'interface Java
[Java] À propos des tableaux
Quelque chose à propos de java
Où est Java
À propos des fonctionnalités Java
À propos des threads Java
Interface [Java]
À propos de la classe Java
Java et JavaScript
À propos des tableaux Java
XXE et Java
À propos de l'héritage Java
À propos de Java Var
À propos de Java Literal
À propos des commandes Java
Ceci et celui de la dérivation conditionnelle du développement des rails
À propos de la sortie du journal Java
À propos de l'interface fonctionnelle Java
Java, à propos d'un tableau à deux dimensions
À propos de la division de classe (Java)
À propos de [Java] [StreamAPI] allMatch ()
Getter et Setter (Java)
À propos de la classe Java StringBuilder
[Java] Thread et exécutable
Java vrai et faux
[Java] À propos de la classe Singleton
À propos des classes et des instances
[Java] Comparaison des chaînes de caractères et && et ||
[Java] À propos des classes anonymes
A propos des méthodes de fractionnement (Java)
À propos de gets et gets.chomp
[Java Silver] À propos de l'initialisation
A propos de la liste des baies Java
À propos du polymorphisme Java Super ()
À propos de la redirection et du transfert
[Java] À propos de Objects.equals () et examen de la comparaison de chaînes (== et égal à)
À propos de la classe Java String
Java - Sérialisation et désérialisation
[Java] Arguments et paramètres
À propos des modificateurs d'accès Java
A propos du type de données de base Java et de la mémoire du type de référence
À propos de l'encapsulation et de l'héritage