Java Mac操作系统中的特殊密钥

Java Mac操作系统中的特殊密钥,java,macos,io,Java,Macos,Io,我在写一个维格纳密码。它适用于普通字符,但当我在Mac键盘上使用额外字符(例如使用option和c)时,它会中断。是因为它超出了字符范围吗 Output using read byte individually hello testing long output!@#)!(!*!(@()asdfasdfljkasdfjË©âå¬ÃËââÃ¥ËÃâçËâËøÅËèâÏåøà Output using read(byte[]) hello testing long output!@

我在写一个维格纳密码。它适用于普通字符,但当我在Mac键盘上使用额外字符(例如使用option和c)时,它会中断。是因为它超出了字符范围吗

Output using read byte individually
hello testing long output!@#)!(!*!(@()asdfasdfljkasdfjË©âå¬ÃËââÃ¥ËÃâçËâËøÅËèâÏåøÃ
Output using read(byte[])
hello testing long output!@#)!(!*!(@()asdfasdfljkasdfjᅨルᅡᄅ¬ネニᅢᆬᅡᆲᅢ゚ᅨレ¬ネツ¬ネニᅢᆬᅨルᅢ゚¬ネニᅢ뎨ニ¬ネムᅨニᅢ쟤モᅨニᅢ゚ᅡᄄ¬ネツᅬタᅢᆬᅢ재゚
代码:

import java.io.*;
类VigenerFileInputStream扩展了FilterInputStream{
私有最终字节[]密钥;
私有整数指数=0;
VigenerFileInputStream(InputStream输入,字节[]k){
超级(in),;
key=k.clone();
}
public int read()引发IOException{
int c=super.read();
如果(c==-1)
返回-1;
int out=c^键[索引];
索引++;
索引%=关键字长度;
返回;
}
公共整数读取(字节[]b)引发IOException{
int结果=in.read(b);
for(int i=0;i
系统输出打印((char)c);
”您不是在读
字符,而是在读
字节。字节
(8位)和
字符
(16位Unicode)之间的差异这是一个漫长而复杂的主题…超出了StackOverflow的详细解释范围。但是:Vignere密码假定一个特定的字母表,以便可以完成旋转。如果提供已知字母表之外的字符,则会发生未定义的行为。
import java.io.*;

class VigenereFilterInputStream extends FilterInputStream {
    private final byte[] key;
    private int index = 0;

    VigenereFilterInputStream(InputStream in, byte[] k) {
        super(in);
        key = k.clone();
    }

    public int read() throws IOException {
        int c = super.read();

        if (c == -1) 
            return -1;

        int out = c ^ key[index];
        index ++;
        index %= key.length;
        return out;
    }

    public int read(byte[] b) throws IOException {
        int result = in.read(b);
        for(int i = 0; i < b.length; i++) {
            b[i] = (byte) (b[i] ^ key[i % key.length]);
        }
        return result;
    }
}

class VigenereFilterOutputStream extends FilterOutputStream {
    private final byte[] key;

    VigenereFilterOutputStream(OutputStream out, byte[] k) {
        super(out);
        key = k.clone();
    }

    public void write(byte[] b) throws IOException {
        byte[] out = new byte[b.length];

        for(int i = 0; i < b.length; i++) {
            out[i] = (byte) (b[i] ^ key[i % key.length]);
        }
        super.write(out);
    }
}

class Vigenere {
    public static void main(String[] args) throws Exception {
        if (args.length != 1) {
            throw new Exception("Missing filename");
        }

        File f = new File(args[0]);

        byte[] text = "hello testing long output!@#)!(!*!(@()asdfasdfljkasdfj˙©∆å¬ß˚∂∆å˙ß∆çˆ∑ˆøœˆß¨∂πåøß".getBytes();
        byte[] key = "hello".getBytes();

        FileOutputStream os = new FileOutputStream(f);
        VigenereFilterOutputStream encrypt = new VigenereFilterOutputStream(os, key);

        encrypt.write(text);

        FileInputStream is = new FileInputStream(f);
        BufferedInputStream bis = new BufferedInputStream(is);
        VigenereFilterInputStream decrypt = new VigenereFilterInputStream(bis, key);

        bis.mark(text.length);
        int c;
        while((c = decrypt.read()) != -1) {
            System.out.print((char) c);
        }

        System.out.println();

        bis.reset();
        byte[] b = new byte[text.length];
        decrypt.read(b);

        for(byte d: b) {
            System.out.print((char) d);
        }
        System.out.println();
    }
}