Java 如何使用 XOR 开发 OTPInputStream
How to use XOR to develop a OTPInputStream in Java
我想在 Java 中开发一个 OTPInputStream
来扩展 InputStream
并获取另一个密钥数据输入流并提供一个流加密/解密输入stream.I需要开发一个测试程序来展示使用XOR和任意数据的OTPInputStream
的使用。
我尝试使用此代码,但遇到问题
java.io.FileInputStream
cannot be cast to java.lang.CharSequence
我应该在这里做什么?
public class Bitwise_Encryption {
static String file = "" ;
static String key = "VFGHTrbg";
private static int[] encrypt(FileInputStream file, String key) {
int[] output = new int[((CharSequence) file).length()];
for(int i = 0; i < ((CharSequence) file).length(); i++) {
int o = (Integer.valueOf(((CharSequence) file).charAt(i)) ^ Integer.valueOf(key.charAt(i % (key.length() - 1)))) + '0';
output[i] = o;
}
return output;
}
private static String decrypt(int[] input, String key) {
String output = "";
for(int i = 0; i < input.length; i++) {
output += (char) ((input[i] - 48) ^ (int) key.charAt(i % (key.length() - 1)));
}
return output;
}
public static void main(String args[]) throws FileNotFoundException {
FileInputStream file = new FileInputStream("directory");
encrypt(file,key);
//decrypt();
int[] encrypted = encrypt(file,key);
System.out.println("Encrypted Data is :");
for(int i = 0; i < encrypted.length; i++)
System.out.printf("%d,", encrypted[i]);
System.out.println("");
System.out.println("---------------------------------------------------");
System.out.println("Decrypted Data is :");
System.out.println(decrypt(encrypted,key));
}
}
想想你想要的只是file.read()
和file.getChannel().size()
一次读取一个字符并获取文件的大小
尝试这样的事情:
private static int[] encrypt(FileInputStream file, String key) {
int fileSize = file.getChannel().size();
int[] output = new int[fileSize];
for(int i = 0; i < output.length; i++) {
char char1 = (char) file.read();
int o = (char1 ^ Integer.valueOf(key.charAt(i % (key.length() - 1)))) + '0';
output[i] = o;
}
return output;
}
将不得不做一些错误处理,因为如果到达文件末尾,file.read() 将 return -1 并且正如指出的那样,一次读取一个字节很多IO 操作并会降低性能。您可以将数据保存在缓冲区中并像这样以另一种方式读取它:
private static int[] encrypt(FileInputStream file, String key) {
int fileSize = file.getChannel().size();
int[] output = new int[fileSize];
int read = 0;
int offset = 0;
byte[] buffer = new byte[1024];
while((read = file.read(buffer)) > 0) {
for(int i = 0; i < read; i++) {
char char1 = (char) buffer[i];
int o = (char1 ^ Integer.valueOf(key.charAt(i % (key.length() - 1)))) + '0';
output[i + offset] = o;
}
offset += read;
}
return output;
}
这将从文件中一次读取 1024 个字节并将其存储在您的缓冲区中,然后您可以循环遍历缓冲区以执行您的逻辑。偏移值用于存储当前点在我们的输出中的位置。此外,您还必须确保 i + offset
不超过您的数组大小。
更新
使用它之后;我决定切换到 Base64 Encoding/Decoding 以删除不可打印的字符:
private static String encrypt(InputStream file, String key) throws Exception {
int read = 0;
byte[] buffer = new byte[1024];
try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
while((read = file.read(buffer)) > 0) {
baos.write(buffer, 0, read);
}
return base64Encode(xorWithKey(baos.toByteArray(), key.getBytes()));
}
}
private static String decrypt(String input, String key) {
byte[] decoded = base64Decode(input);
return new String(xorWithKey(decoded, key.getBytes()));
}
private static 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 static byte[] base64Decode(String s) {
return Base64.getDecoder().decode(s.trim());
}
private static String base64Encode(byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
}
此方法更简洁,不需要知道 InputStream
的大小或进行任何字符转换。它将您的 InputStream
读入 OutputStream 以进行 Base64 编码并删除不可打印的字符。
我已经测试过了,它可以用于加密和解密。
我从这个答案中得到了灵感:
XOR operation with two strings in java
我想在 Java 中开发一个 OTPInputStream
来扩展 InputStream
并获取另一个密钥数据输入流并提供一个流加密/解密输入stream.I需要开发一个测试程序来展示使用XOR和任意数据的OTPInputStream
的使用。
我尝试使用此代码,但遇到问题
java.io.FileInputStream
cannot be cast tojava.lang.CharSequence
我应该在这里做什么?
public class Bitwise_Encryption {
static String file = "" ;
static String key = "VFGHTrbg";
private static int[] encrypt(FileInputStream file, String key) {
int[] output = new int[((CharSequence) file).length()];
for(int i = 0; i < ((CharSequence) file).length(); i++) {
int o = (Integer.valueOf(((CharSequence) file).charAt(i)) ^ Integer.valueOf(key.charAt(i % (key.length() - 1)))) + '0';
output[i] = o;
}
return output;
}
private static String decrypt(int[] input, String key) {
String output = "";
for(int i = 0; i < input.length; i++) {
output += (char) ((input[i] - 48) ^ (int) key.charAt(i % (key.length() - 1)));
}
return output;
}
public static void main(String args[]) throws FileNotFoundException {
FileInputStream file = new FileInputStream("directory");
encrypt(file,key);
//decrypt();
int[] encrypted = encrypt(file,key);
System.out.println("Encrypted Data is :");
for(int i = 0; i < encrypted.length; i++)
System.out.printf("%d,", encrypted[i]);
System.out.println("");
System.out.println("---------------------------------------------------");
System.out.println("Decrypted Data is :");
System.out.println(decrypt(encrypted,key));
}
}
想想你想要的只是file.read()
和file.getChannel().size()
一次读取一个字符并获取文件的大小
尝试这样的事情:
private static int[] encrypt(FileInputStream file, String key) {
int fileSize = file.getChannel().size();
int[] output = new int[fileSize];
for(int i = 0; i < output.length; i++) {
char char1 = (char) file.read();
int o = (char1 ^ Integer.valueOf(key.charAt(i % (key.length() - 1)))) + '0';
output[i] = o;
}
return output;
}
将不得不做一些错误处理,因为如果到达文件末尾,file.read() 将 return -1 并且正如指出的那样,一次读取一个字节很多IO 操作并会降低性能。您可以将数据保存在缓冲区中并像这样以另一种方式读取它:
private static int[] encrypt(FileInputStream file, String key) {
int fileSize = file.getChannel().size();
int[] output = new int[fileSize];
int read = 0;
int offset = 0;
byte[] buffer = new byte[1024];
while((read = file.read(buffer)) > 0) {
for(int i = 0; i < read; i++) {
char char1 = (char) buffer[i];
int o = (char1 ^ Integer.valueOf(key.charAt(i % (key.length() - 1)))) + '0';
output[i + offset] = o;
}
offset += read;
}
return output;
}
这将从文件中一次读取 1024 个字节并将其存储在您的缓冲区中,然后您可以循环遍历缓冲区以执行您的逻辑。偏移值用于存储当前点在我们的输出中的位置。此外,您还必须确保 i + offset
不超过您的数组大小。
更新
使用它之后;我决定切换到 Base64 Encoding/Decoding 以删除不可打印的字符:
private static String encrypt(InputStream file, String key) throws Exception {
int read = 0;
byte[] buffer = new byte[1024];
try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
while((read = file.read(buffer)) > 0) {
baos.write(buffer, 0, read);
}
return base64Encode(xorWithKey(baos.toByteArray(), key.getBytes()));
}
}
private static String decrypt(String input, String key) {
byte[] decoded = base64Decode(input);
return new String(xorWithKey(decoded, key.getBytes()));
}
private static 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 static byte[] base64Decode(String s) {
return Base64.getDecoder().decode(s.trim());
}
private static String base64Encode(byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
}
此方法更简洁,不需要知道 InputStream
的大小或进行任何字符转换。它将您的 InputStream
读入 OutputStream 以进行 Base64 编码并删除不可打印的字符。
我已经测试过了,它可以用于加密和解密。
我从这个答案中得到了灵感:
XOR operation with two strings in java