首页 > 试题广场 >

凯撒密码

[编程题]凯撒密码
  • 热度指数:710 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
一段由凯撒密码加密过的密文,凯撒密码指的是将字符偏移一定的单位,例如若偏移量为2,则a替换为c,b替换为d,c替换为e,...,z替换为b。若加密nowcoder,则密文为pqyeqfgt。现在发现加密包括数字、大写字母、小写字母,即0-9、A-Z、a-z的排列顺序进行偏移,现在截获了对方的一段密文以及偏移量,给定一段密文str和偏移量d,求对应的明文。

示例1

输入

"pqyeqfgt",2

输出

"nowcoder"
示例2

输入

"123ABCabc",3

输出

"yz0789XYZ"

备注:
,d为加密时的偏移量
char* decode(char* str, int d ) {
  // code == 密码本
  const char* code = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  char* ans = (char*) calloc(1001, sizeof(char));
  int index;
  while (*str) {
    index = strchr(code, *str) - code;
    strncat(ans, index - d < 0 
            ? code + (62 + (index - d)) 
            : code + (index - d), 1);
    ++str;
  }
  return ans;
}

发表于 2021-07-30 08:45:52 回复(0)
笨方法,分别做字符到数字和数字到字符的映射,然后向左偏移字符,如果偏移后为负数,则对偏移后的值加上62(10个数字和大小写字母的个数),否则直接向左偏移。
import java.util.*;


public class Solution {
    /**
     * 解密密文
     * @param str string字符串 密文
     * @param d int整型 偏移量
     * @return string字符串
     */
    public String decode (String str, int d) {
        // write code here
        HashMap<Character, Integer> map = new HashMap<>();
        HashMap<Integer, Character> inverseMap = new HashMap<>();
        for(int i = 0; i <= 9; i++){
            map.put((char)('0' + i), i);
            inverseMap.put(i, (char)('0' + i));
        }
        for(int i = 0; i <= 25; i++){
            map.put((char)('A' + i), i + 10);
            inverseMap.put(i + 10, (char)('A' + i));
        }
        for(int i = 0; i <= 25; i++){
            map.put((char)('a' + i), i + 36);
            inverseMap.put(i + 36, (char)('a' + i));
        }
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < str.length(); i++){
            char c = str.charAt(i);
            if(map.get(c) - map.get('0') >= d){
                sb.append(inverseMap.get(map.get(c) - d));
            }else
                sb.append(inverseMap.get(map.get(c) - d + 62));
        }
        return sb.toString();
    }
}

发表于 2021-05-21 10:31:26 回复(0)
为什么感觉题意和答案的不一致?
发表于 2021-07-25 16:27:18 回复(0)

是我想多了,一直在想怎么通过ASCII解决问题

func decode(str string, d int) string {
    // write code here
    abracadabra := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" //97 122 48 57 65 90
    abc := []byte(abracadabra)
    l := len(abc)
    //log.Info.Println(l)
    offset := d % 62
    //log.Info.Println(offset)
    b := []byte(str)
    passwd := []byte{}
    for i := 0; i < len(b); i++ { //加密文本
        for j := 0; j < l; j++ {
            if b[i] == abc[j] {
                if j-offset >= 0 {
                    passwd = append(passwd, abc[j-offset])
                } else {
                    passwd = append(passwd, abc[j-offset+62])
                }
            }
        }
    }
    ret := string(passwd)
    return ret
}
编辑于 2021-06-13 18:21:02 回复(0)
 public String decode (String str, int d) {
        String order = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        char[]array=str.toCharArray();
        int n = 62;
        int index = 0;
        for(int i=0; i<str.length(); i++){
            char cha=array[i];
            if(cha>='0'&&cha<='9')
                index = cha-'0';
            else if(cha>='A' && cha<='Z')
                index = 10 + (cha - 'A');
            else
                index = 36 + (cha - 'a');
            index = (index + n - d) % n;
            array[i] = order.charAt(index);
        }
        return String.valueOf(array);
    }

发表于 2021-03-31 17:10:54 回复(0)