使用java中的vigenere加密加密字节数组 [英] Encrypt byte array using vigenere cipher in java
问题描述
@Override
public byte [] encryptFile(byte [] file,String key){
char [] keyChars = key.toCharArray();
byte [] bytes = file; (int i = 0; i< file.length; i ++){
int keyNR = keyChars [i%keyChars.length] - 32;
int c = bytes [i]& 255;
if((c> = 32)&&(c <= 127)){
int x = c - 32;
x =(x + keyNR)%96;
bytes [i] =(byte)(x + 32);
}
}
返回字节;
}
@Override
public byte [] decryptFile(byte [] file,String key){
char [] keyChars = key.toCharArray ();
byte [] bytes = file; (int i = 0; i< file.length; i ++){
int keyNR = keyChars [i%keyChars.length] - 32;
int c = bytes [i]& 255;
if((c> = 32)&&(c <= 127)){
int x = c - 32;
x =(x - keyNR + 96)%96;
bytes [i] =(byte)(x + 32);
}
}
返回字节;
}
我做错了什么?
编辑:
阅读和写入文件:
public void sendFile(String selectedFile,ICipher cipher,String key){
try {
DataOutputStream outStream = new DataOutputStream(client
.getOutputStream());
outStream.flush();
文件文件= new File(selectedFile);
FileInputStream fileStream = new FileInputStream(file);
long fileSize = file.length();
long completed = 0;
long bytesLeft = fileSize - completed;
String msg =SENDING_FILE:+ file.getName()+:+ fileSize;
outStream.writeUTF(cipher.encryptMsg(msg,key));
while(completed< fileSize){
int step =(int)(bytesLeft> 150000?150000:bytesLeft);
byte [] buffer = new byte [step];
fileStream.read(buffer);
buffer = cipher.encryptFile(buffer,key);
outStream.write(buffer);
完成+ =步;
bytesLeft = fileSize - completed;
}
outStream.writeUTF(cipher.encryptMsg(SEND_COMPLETE,key));
fileStream.close();
} catch(IOException e){
e.printStackTrace();
}
}
private void downloadFile(String fileName,int fileSize,DataInputStream input,ICipher cipher,String key){
try {
FileOutputStream outStream = new FileOutputStream(C:\\+ fileName);
int bytesRead = 0,counter = 0;
while(counter< fileSize){
int step =(int)(fileSize> 150000?150000:fileSize);
byte [] buffer = new byte [step];
bytesRead = input.read(buffer);
if(bytesRead> = 0){
buffer = cipher.decryptFile(buffer,key);
outStream.write(buffer,0,bytesRead);
counter + = bytesRead;
}
if(bytesRead< 1024){
outStream.flush();
break;
}
}
Display.getDefault()。syncExec(new Runnable(){
@Override
public void run(){
window.handleMessage(成功下载);
}
});
outStream.close();
} catch(Exception e){
Display.getDefault()。syncExec(new Runnable(){
@Override
public void run(){
window.handleMessage(下载文件时出错!);
}
});
}
}
你以任何来自磁盘I / O的块编码文件:
int step =(int)(bytesLeft> 150000? 150000:bytesLeft);
byte [] buffer = new byte [step];
fileStream.read(buffer);
buffer = cipher.encryptFile(buffer,key);
但是您可以以任何来自网络I / O的块解码文件:
bytesRead = input.read(buffer);
if(bytesRead> = 0){
buffer = cipher.decryptFile(buffer,key);
outStream.write(buffer,0,bytesRead);
counter + = bytesRead;
}
这些块很可能不同意。磁盘I / O可能总是给你完整的块(对你来说很幸运),但网络I / O可能会给你分组大小的块(1500字节减去标题)。
密码应该获得已经编码/解码的数据的偏移量(或一次编码/解码所有内容),并使用它来适当地移动密钥,或者这可能发生:
原始:... LOREM IPSUM ...
键:... abCde abCde ...
编码:... MQUIR JRVYR ...
键:... abCde Cdeab ...<<<<注意键被移动
解码:... LOREM GNQXP .. 。<<在第一个块之后输出错误。
由于分组数据大小(以太网大小的TCP / IP数据包)以四个字节对齐,长度为4的键可能总是对齐。
另一个问题是您忽略读取的字节数从磁盘上传文件时。虽然磁盘I / O可能总是给您全尺寸的块(该文件可能是内存映射或底层本机API提供此保证),但没有任何理由认为是理所当然的。始终使用实际读取的字节数: bytesRead = fileStream.read(buffer);
I have to encrypt some file (jpg) using vigenere cipher. I wrote some code, but after encryption and decryption my file is corrupted. The first 1/4 of image displays okay, but the rest of it is corrupted. Here is my code:
@Override
public byte[] encryptFile(byte[] file, String key) {
char[] keyChars = key.toCharArray();
byte[] bytes = file;
for (int i = 0; i < file.length; i++) {
int keyNR = keyChars[i % keyChars.length] - 32;
int c = bytes[i] & 255;
if ((c >= 32) && (c <= 127)) {
int x = c - 32;
x = (x + keyNR) % 96;
bytes[i] = (byte) (x + 32);
}
}
return bytes;
}
@Override
public byte[] decryptFile(byte[] file, String key) {
char[] keyChars = key.toCharArray();
byte[] bytes = file;
for (int i = 0; i < file.length; i++) {
int keyNR = keyChars[i % keyChars.length] - 32;
int c = bytes[i] & 255;
if ((c >= 32) && (c <= 127)) {
int x = c - 32;
x = (x - keyNR + 96) % 96;
bytes[i] = (byte) (x + 32);
}
}
return bytes;
}
What did I do wrong?
EDIT:
reading and writing to file:
public void sendFile(String selectedFile, ICipher cipher, String key) {
try {
DataOutputStream outStream = new DataOutputStream(client
.getOutputStream());
outStream.flush();
File file = new File(selectedFile);
FileInputStream fileStream = new FileInputStream(file);
long fileSize = file.length();
long completed = 0;
long bytesLeft = fileSize - completed;
String msg = "SENDING_FILE:" + file.getName() + ":" + fileSize;
outStream.writeUTF(cipher.encryptMsg(msg, key));
while (completed < fileSize) {
int step = (int) (bytesLeft > 150000 ? 150000 : bytesLeft);
byte[] buffer = new byte[step];
fileStream.read(buffer);
buffer = cipher.encryptFile(buffer, key);
outStream.write(buffer);
completed += step;
bytesLeft = fileSize - completed;
}
outStream.writeUTF(cipher.encryptMsg("SEND_COMPLETE", key));
fileStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void downloadFile(String fileName, int fileSize,DataInputStream input,ICipher cipher, String key) {
try {
FileOutputStream outStream = new FileOutputStream("C:\\" + fileName);
int bytesRead = 0, counter = 0;
while (counter < fileSize) {
int step = (int) (fileSize > 150000 ? 150000 : fileSize);
byte[] buffer = new byte[step];
bytesRead = input.read(buffer);
if (bytesRead >= 0) {
buffer = cipher.decryptFile(buffer, key);
outStream.write(buffer, 0, bytesRead);
counter += bytesRead;
}
if (bytesRead < 1024) {
outStream.flush();
break;
}
}
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
window.handleMessage("Download sucessfully");
}
});
outStream.close();
} catch (Exception e) {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
window.handleMessage("Error on downloading file!");
}
});
}
}
You encode the file in whatever chunks come from the disk I/O:
int step = (int) (bytesLeft > 150000 ? 150000 : bytesLeft);
byte[] buffer = new byte[step];
fileStream.read(buffer);
buffer = cipher.encryptFile(buffer, key);
But you decode the file in whatever chunks come from the network I/O:
bytesRead = input.read(buffer);
if (bytesRead >= 0) {
buffer = cipher.decryptFile(buffer, key);
outStream.write(buffer, 0, bytesRead);
counter += bytesRead;
}
These chunks are likely to disagree. The disk I/O may always give you full chunks (lucky for you), but the network I/O will likely give you packet-sized chunks (1500 bytes minus header).
The cipher should get an offset into the already encoded/decoded data (or encode/decode everything at once), and use that to shift the key appropriately, or this may happen:
original: ...LOREM IPSUM...
key : ...abCde abCde...
encoded : ...MQUIR JRVYR...
key : ...abCde Cdeab... <<note the key got shifted
decoded : ...LOREM GNQXP... <<output wrong after the first chunk.
Since the packet data size is (for Ethernet-sized TCP/IP packets) aligned at four bytes, a key of length four is likely to be always aligned.
another issue is that you are ignoring the number of bytes read from disk when uploading the file. While disk I/O is likely to always give you full-sized chunks (the file's likely to be memory-mapped or the underlying native API does provide this guarantee), nothing's taken for granted. Always use the amount of bytes actually read: bytesRead = fileStream.read(buffer);
这篇关于使用java中的vigenere加密加密字节数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!