son que operadores operador maneja los disyuncion cuáles conjuncion asignación java string operators xor

java - que - operadores bit



Operación XOR con dos cadenas en java (7)

Cómo hacer una operación XOR en modo bit a dos cadenas en java.


Esta solución es compatible con Android (lo he probado y usado yo mismo). Gracias a @ user467257 cuya solución adapté esto.

import android.util.Base64; public class StringXORer { public String encode(String s, String key) { return new String(Base64.encode(xorWithKey(s.getBytes(), key.getBytes()), Base64.DEFAULT)); } public String decode(String s, String key) { return new String(xorWithKey(base64Decode(s), key.getBytes())); } private byte[] xorWithKey(byte[] a, byte[] key) { byte[] out = new byte[a.length]; for (int i = 0; i < a.length; i++) { out[i] = (byte) (a[i] ^ key[i%key.length]); } return out; } private byte[] base64Decode(String s) { return Base64.decode(s,Base64.DEFAULT); } private String base64Encode(byte[] bytes) { return new String(Base64.encode(bytes,Base64.DEFAULT)); } }


Este es el código que estoy usando:

private static byte[] xor(final byte[] input, final byte[] secret) { final byte[] output = new byte[input.length]; if (secret.length == 0) { throw new IllegalArgumentException("empty security key"); } int spos = 0; for (int pos = 0; pos < input.length; ++pos) { output[pos] = (byte) (input[pos] ^ secret[spos]); ++spos; if (spos >= secret.length) { spos = 0; } } return output; }


Nota: esto solo funciona para caracteres bajos, es decir, debajo de 0x8000, Esto funciona para todos los caracteres ASCII.

Haría un XOR cada charAt () para crear una nueva cadena. Me gusta

String s, key; StringBuilder sb = new StringBuilder(); for(int i = 0; i < s.length(); i++) sb.append((char)(s.charAt(i) ^ key.charAt(i % key.length()))); String result = sb.toString();

En respuesta al comentario de @ user467257

Si su entrada / salida es utf-8 y usted xor "a" y "æ", le queda una cadena de utf-8 no válida que consta de un carácter (decimal 135, un carácter de continuación).

Son los valores de char que se están marcando, pero los valores de byte y esto producen un carácter que se codifica en UTF-8.

public static void main(String... args) throws UnsupportedEncodingException { char ch1 = ''a''; char ch2 = ''æ''; char ch3 = (char) (ch1 ^ ch2); System.out.println((int) ch3 + " UTF-8 encoded is " + Arrays.toString(String.valueOf(ch3).getBytes("UTF-8"))); }

huellas dactilares

135 UTF-8 encoded is [-62, -121]


Quieres algo como esto:

import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import java.io.IOException; public class StringXORer { public String encode(String s, String key) { return base64Encode(xorWithKey(s.getBytes(), key.getBytes())); } public String decode(String s, String key) { return new String(xorWithKey(base64Decode(s), key.getBytes())); } private byte[] xorWithKey(byte[] a, byte[] key) { byte[] out = new byte[a.length]; for (int i = 0; i < a.length; i++) { out[i] = (byte) (a[i] ^ key[i%key.length]); } return out; } private byte[] base64Decode(String s) { try { BASE64Decoder d = new BASE64Decoder(); return d.decodeBuffer(s); } catch (IOException e) {throw new RuntimeException(e);} } private String base64Encode(byte[] bytes) { BASE64Encoder enc = new BASE64Encoder(); return enc.encode(bytes).replaceAll("//s", ""); } }

La codificación de base64 se realiza porque al xorar los bytes de una cadena no se pueden devolver bytes válidos para una cadena.


Suponiendo (!) Que las cadenas tienen la misma longitud, ¿por qué no convertirlas a matrices de bytes y luego XOR los bytes? Las matrices de bytes resultantes también pueden tener diferentes longitudes dependiendo de su codificación (por ejemplo, UTF8 se expandirá a diferentes longitudes de bytes para diferentes caracteres).

Debe tener cuidado de especificar la codificación de caracteres para garantizar una conversión de cadena / byte consistente / confiable.


la función abs es cuando las cuerdas no tienen la misma longitud, por lo que la parte final del resultado será la misma que la longitud mínima de las dos cuerdas a y b

public String xor(String a, String b){ StringBuilder sb = new StringBuilder(); for(int k=0; k < a.length(); k++) sb.append((a.charAt(k) ^ b.charAt(k + (Math.abs(a.length() - b.length()))))) ; return sb.toString(); }


Presta atención:

Un char Java corresponde a una unidad de código UTF-16 y, en algunos casos, se necesitan dos caracteres consecutivos (el llamado par suplente ) para un carácter Unicode real (punto de código).

XORAR dos secuencias UTF-16 válidas (es decir, las cadenas Java char por char , o byte por byte después de codificar en UTF-16) no necesariamente le da otra cadena UTF-16 válida; como resultado, puede tener sustitutos no emparejados. (Todavía sería una cadena de Java perfectamente utilizable, solo los métodos relativos al punto de código podrían confundirse, y los que se convierten a otras codificaciones para salida y similares).

Lo mismo es válido si primero convierte sus Strings a UTF-8 y luego XOR a estos bytes. En este caso es muy probable que termine con una secuencia de bytes que no es válida para UTF-8, si sus Strings no eran ambas cadenas ASCII puras.

Incluso si intenta hacerlo correctamente e iterar sobre sus dos Cadenas por punto de código e intenta XOR los puntos de código, puede terminar con puntos de código fuera del rango válido (por ejemplo, U+FFFFF (plano 15) XOR U+10000 (plano 16) = U+1FFFFF (que sería el último carácter del plano 31), muy por encima del rango de puntos de código existentes. Y también podría terminar de esta manera con puntos de código reservados para sustitutos (= no válidos).

Si sus cadenas solo contienen caracteres <128, 256, 512, 1024, 2048, 4096, 8192, 16384 o 32768, entonces las cadenas XORed (con caracteres) estarán en el mismo rango y, por lo tanto, no contendrán sustitutos. En los dos primeros casos, también podría codificar su String como ASCII o Latin-1, respectivamente, y tener el mismo resultado XOR para los bytes. (Aún puede terminar con caracteres de control, lo que puede ser un problema para usted).

Lo que finalmente estoy diciendo aquí : no espere que el resultado de cifrar las Cadenas vuelva a ser una cadena válida, en lugar de eso, simplemente almacénelo y transmítalo como un byte[] (o un flujo de bytes). (Y sí, convierta a UTF-8 antes de cifrar, y de UTF-8 después de descifrar).