我需要一个简单的c#算法,该算法将采用一串x字符并将其'加密'为另一个x字符串。它不必是安全的,但不应该只通过查看加密字符串来重建原始字符串。例如,如果我输入“你好”,我应该得到像“x = w3q”的东西。它不应该简单地将每个角色映射到其他角色,但它不必比这更复杂。它需要是对称的,所以我需要能够从“x = w3q”构造“hello”。加密字符串以匹配原始字符串的长度
到目前为止,我已经尝试过RijndaelManaged和RSA加密,但加密的字符串比原始字符串长很多。
任何想法?
我需要一个简单的c#算法,该算法将采用一串x字符并将其'加密'为另一个x字符串。它不必是安全的,但不应该只通过查看加密字符串来重建原始字符串。例如,如果我输入“你好”,我应该得到像“x = w3q”的东西。它不应该简单地将每个角色映射到其他角色,但它不必比这更复杂。它需要是对称的,所以我需要能够从“x = w3q”构造“hello”。加密字符串以匹配原始字符串的长度
到目前为止,我已经尝试过RijndaelManaged和RSA加密,但加密的字符串比原始字符串长很多。
任何想法?
您可以使用ROT13算法开始,然后根据以前的字符更改偏移量。
例: “你好”
ROT13为 'H' - > 'U'
由于U是字母表中的第21封信,你会在下次使用ROT21:
ROT8为'e' - >'z'
等等。
这不仅会保持长度不变,还可以处理额外的字符,只要您将它们添加到字母表。
我很抱歉,如果现在还不够清楚,我正在打电话。
编辑:
下面是一些代码,这将使很多更有意义:
static String alphabet = "abcdefghijklmnopqrstuvwxyz";
public static String encrypt(String originalString)
{
String returnString = "";
int shift = alphabet.Length/2;
foreach (char c in originalString)
{
int nextIndex = alphabet.IndexOf(c) + shift;
if (nextIndex > alphabet.Length)
nextIndex = nextIndex - alphabet.Length;
returnString += alphabet[nextIndex];
shift = alphabet.IndexOf(alphabet[nextIndex]);
}
return returnString;
}
public static String decrypt(String encryptedString)
{
String returnString = "";
int shift = alphabet.Length/2;
foreach (char c in encryptedString)
{
int nextIndex = alphabet.IndexOf(c) - shift;
if (nextIndex < 0)
nextIndex = alphabet.Length + nextIndex; // nextIndex is negative so we are decreasing regardless
returnString += alphabet[nextIndex];
shift = alphabet.IndexOf(c);
}
return returnString;
}
的字母可以根据需要尽可能多的扩大。这并不安全,但它很简单,仅通过查看就不能轻易破译。
您可以根据字符的索引映射到不同的字符,这只是使其不太明显。
private static readonly int[] charOffsets = new[]{30,26,39,...};
private static char EncryptChar(char c, int index)
{
return (char)(c + charOffests[index % charOffsets.Length]);
}
private static char DecryptChar(char c, int index)
{
return (char)(c - charOffests[index % charOffsets.Length]);
}
public static string Encrypt(string str)
{
return new string(str.Select((c, i) => EncryptChar(c, i)));
}
public static string Decrypt(string str)
{
return new string(str.Select((c, i) => DecryptChar(c, i)));
}
你可以用它调整,如果一点点,你只想要字母等,但你的想法,我希望。
谢谢,希望有内置的东西,但猜测它太简单了! – Johan
如果你想要一个众所周知的(古典)密码这里是一个Vigenère的实现。
import java.util.EnumSet;
import java.util.Set;
/**
* Simple object oriented implementation of the classical Vigenère cipher.
* Note that Vigenère is - of course - not considered secure anymore.
*
* @author maartenb
*/
public class Vigenère {
private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final int LA = ALPHABET.length();
/**
* Flags to be used for the Vigenère cipher.
*/
public enum Flag {
/**
* Do not encrypt/decrypt space characters but leave them in the same
* position.
*/
SKIP_SPACE;
}
private enum State {
INSTANTIATED, INITIALIZED;
}
private enum Operation {
ENCRYPT, DECRYPT;
public int direction() {
switch (this) {
case ENCRYPT:
return 1;
case DECRYPT:
return -1;
default:
throw new IllegalStateException();
}
}
}
private State state = State.INSTANTIATED;
private String key;
private int lk;
private Set<Flag> flags;
/**
* Initializes the cipher with the given key.
*
* @param key
* the key that can only use the characters in the alphabet
* @param flags
* option flag parameters
* @throws IllegalArgumentException
* if the key contains invalid characters
*/
public void init(final String key, final Set<Flag> flags) {
if (key == null || key.isEmpty()) {
throw new IllegalArgumentException("Key null or empty");
}
this.lk = key.length();
for (int i = 0; i < this.lk; i++) {
if (ALPHABET.indexOf(key.codePointAt(i)) == -1) {
throw new IllegalArgumentException("Key character nat index "
+ i + " not in alphabet");
}
}
this.key = key;
this.flags = flags;
this.state = State.INITIALIZED;
}
/**
* Encrypts the plaintext using the key set during initialization.
*
* @param plaintext
* the plaintext, using the characters in the alphabet
* @return the ciphertext
* @throws IllegalStateException
* if the cipher wasn't initialized
* @throws IllegalArgumentException
* if the plaintext contains characters not in the alphabet
*/
public String encrypt(final String plaintext) {
if (this.state != State.INITIALIZED) {
throw new IllegalStateException("Not initialized");
}
return crypt(plaintext, Operation.ENCRYPT);
}
/**
* Decrypts the ciphertext using the key set during initialization.
*
* @param ciphertext
* the ciphertext, using the characters in the alphabet
* @return the plaintext
* @throws IllegalStateException
* if the cipher wasn't initialized
* @throws IllegalArgumentException
* if the ciphertext contains characters not in the alphabet
*/
public String decrypt(final String ciphertext) {
if (this.state != State.INITIALIZED) {
throw new IllegalStateException("Not initialized");
}
return crypt(ciphertext, Operation.DECRYPT);
}
private String crypt(final String in, final Operation op)
throws IllegalStateException, IllegalArgumentException {
final StringBuilder out = new StringBuilder(in.length());
// legend: c = character, k = key, o = offset, in = input, out = output
int skipped = 0;
for (int ino = 0; ino < in.length(); ino++) {
// get character (code point in Unicode)
final int inc = in.codePointAt(ino);
// skip space, if configured
if (inc == ' ' && this.flags.contains(Flag.SKIP_SPACE)) {
out.appendCodePoint(' ');
skipped++;
continue;
}
// get matching key character
final int kc = this.key.codePointAt(mod(ino - skipped, this.lk));
final int kco = ALPHABET.indexOf(kc);
final int inco = ALPHABET.indexOf(inc);
if (inco == -1) {
throw new IllegalArgumentException(
"Invalid character at offset " + ino);
}
// the main calculation
final int outco = mod(inco + op.direction() * kco, LA);
final int outc = ALPHABET.codePointAt(outco);
out.appendCodePoint(outc);
}
return out.toString();
}
private static int mod(final int x, final int n) {
// note that % is the remainder operation in Java
// so it doesn't handle negative values correctly
return (x % n + n) % n;
}
/**
* Main method for testing purposes only.
*
* @param args
* ignored
*/
public static void main(final String[] args) {
// example taken from Wikipedia page on Vigenère
final Vigenère vigenere = new Vigenère();
vigenere.init("LEMON", EnumSet.of(Vigenère.Flag.SKIP_SPACE));
final String ct = vigenere.encrypt("ATTACK AT DAWN");
System.out.println(ct);
final String pt = vigenere.decrypt(ct);
System.out.println(pt);
}
}
我承认,我只是觉得编程它。 –
太好了,谢谢!我会试一试 – Johan
ROT13始终是一种选择! :-) http://en.wikipedia。org/wiki/ROT13 – xanatos
目前尚不清楚您是否想将“人类可读”字符串加密为另一个“人类可读”字符串。你将'hello'转换为'x = w3q',但实际上加密通常是从字节转换为字节,所以它会将'hello'(UTF8)转换为5个随机不可显示的字节。出于这个原因,你经常base64加密的字符串,使其再次可读...但base64放大字符串。 – xanatos
ROT13可以通过简单地查看来轻松重建。 – Amandil