简体   繁体   English

C 中数字的凯撒密码

[英]Caesar's cipher for numbers in C

I want to make a Caesar cipher for numbers.我想为数字制作凯撒密码 (Add 3 to all digits) (所有数字加3)

Input: 52 Output: 85输入:52 输出:85

Input: 954 Output: 287输入:954 输出:287

Input: -10457 Output: -43780输入:-10457 输出:-43780

I'll be very glad if someone helps me with this.如果有人帮助我,我会很高兴。

I tried this but when I input the number less than 5 digits it outputs 3 to beginning.我试过了,但是当我输入小于 5 位的数字时,它会输出 3 到开头。

When I input 52 it outputs 33385. I also want to ask the user whether the program should accept a new number or just exit.当我输入 52 时,它输出 33385。我还想询问用户程序是否应该接受新数字或直接退出。

#include <stdio.h>
#include <stdlib.h>

int main()
{

    int number, operation;

    printf("Enter the number: ");
    scanf("%d", &number);

    printf("%d", ((number / 10000) + 3) % 10);
    printf("%d", (((number % 10000) / 1000) + 3) % 10);
    printf("%d", (((number % 1000) / 100) + 3) % 10);
    printf("%d", (((number % 100) / 10) + 3) % 10);
    printf("%d\n", ((number % 10) + 3) % 10);

    printf("press 1 to continue or 2 for exit.");
    scanf("%d", &operation);

    switch (operation) {
    case 1:
        printf("Enter the number: ");
        scanf("%d", &number);

        printf("%d", ((number / 10000) + 3) % 10);
        printf("%d", (((number % 10000) / 1000) + 3) % 10);
        printf("%d", (((number % 1000) / 100) + 3) % 10);
        printf("%d", (((number % 100) / 10) + 3) % 10);
        printf("%d\n", ((number % 10) + 3) % 10);

        break;

    case 2:

        break;
    }

    return 0;
}

When you enter 52, your number variable takes the value 00052, which will be transformed with your code into 33385. If you don't want the leading 3, you can either not print them, or retrieve the digit first and compute its associated Caesar digit only if the digit is not 0.当您输入 52 时,您的数字变量的值为 00052,它将与您的代码一起转换为 33385。如果您不想要前导 3,您可以不打印它们,或者先检索数字并计算其关联的凯撒仅当数字不为 0 时才为数字。

Another possibility to take into account any int number (whatever the number of digit ) is:考虑任何int数字(无论 digit 的数量)的另一种可能性是:

#include "stdio.h"
#include <stdlib.h>

int main()
{
    int number, abs_number;
    int caesar_number = 0;
    int digit_pos = 1;

    printf("Enter the number: ");
    scanf("%d", &number);

    abs_number = abs(number);

    while (abs_number != 0)
    {
        caesar_number += (((abs_number % 10) + 3) % 10) * digit_pos;
        abs_number /= 10;
        digit_pos *= 10;
    }

    if (number < 0)
    {
        caesar_number = -caesar_number;
    }
    printf("Result is: %d\n", caesar_number);

    return 0;
}

This solution works for all your test cases (positive and negative numbers), for numbers greater than 100000 and for zero as well:此解决方案适用于您的所有测试用例(正数和负数)、大于 100000 的数字以及零:

#include "stdio.h"
#include "stdlib.h"

const int SHIFT = 3;

int main() {
    int number, abs_number, is_negative, operation, result, decimal_place;

    do {
        result = 0;
        decimal_place = 1;

        printf("Enter the number: ");
        scanf("%d", &number);

        // remove the sign before entering the cipher logic...
        abs_number = abs(number);
        // ...but do remember it so we can add it back later
        is_negative = number < 0;

        // from least to most significant decimal place
        do {
            // cipher the digit and accumulate it in the result
            result += (((abs_number % 10) + SHIFT) % 10) * decimal_place;
            // remove the consumed digit from the input variable
            abs_number /= 10;
            // move to the next decimal place
            decimal_place *= 10;
        } while (abs_number > 0);

        printf("Result is: %s%d\n", is_negative ? "-" : "", result);

        printf("Press 1 to continue or 2 for exit.");
        scanf("%d", &operation);

    } while (operation == 1);  // repeat if user requested another cipher

    return 0;
}

Some things to note in your original code:在您的原始代码中需要注意的一些事项:

  • your code doesn't loop.你的代码不会循环。 A switch case won't help you repeat the operation. switch盒不会帮助您重复操作。 You need a while loop for that;你需要一个while循环;
  • it doesn't work for larger numbers: you would have to add an extra line of code to handle numbers greater than 100000... which leads to my next point:它不适用于更大的数字:您必须添加一行额外的代码来处理大于 100000 的数字......这导致了我的下一点:
  • you have repeated code: your logic is duplicated in two different ways.您有重复的代码:您的逻辑以两种不同的方式重复。 The first one is the iteration body.第一个是迭代体。 Even if you replaced the switch statement with a while loop, your first iteration is unnecessarily unrolled outside of the loop.即使您用while循环替换了switch语句,您的第一次迭代也不必要地展开到循环之外。 The second one is the way you handle each decimal place of the input number.第二个是您处理输入数字的每个小数位的方式。 Wouldn't it be better if you had a same code snippet to handle any of the decimal places?如果你有一个相同的代码片段来处理任何小数位不是更好吗? Duplicating code is considered bad practice.复制代码被认为是不好的做法。 It makes the code bigger, it's harder to maintain and easy for duplicated code to get changed in only one place and not in the other.它使代码变得更大,更难维护,而且重复的代码很容易只在一个地方而不是在另一个地方进行更改。 You always want to avoid duplicating code.您总是希望避免重复代码。

Unless the length of user input is not recorded, "Caesar's cipher for numbers" is not reversalable.除非不记录用户输入的长度,否则“凯撒数字密码”是不可逆转的。 With input like "777" , "7" , "000" , "0" , the output needs to be 4 distinctive answers in order to convert back.对于像"777""7""000""0"的输入,输出需要是 4 个不同的答案才能转换回来。

To maintain something of a numeric internal representation, consider using "%n" to keep track of the length of user input.要维护某种数字内部表示,请考虑使用"%n"来跟踪用户输入的长度。

static void print_digits(int a, int length, int offset) {
  if (length > 1) {
    print_digits(a/10, length-1);
  }
  putchar((a+offset)%10 + '0');
}

... ...

#define OFFSET 3

int number;
int n1, n2;
int offset = OFFSET % 10;
if (offset < 10) offset += 10; // Handle negative OFFSET

printf("Enter the number: ");
if (scanf(" %n%d%n", &n1, &number, &n2) == 1) {
  int length = n2 - n1;
  if (number < 0) {
    putchar('-');
    number = -number;
    length--;
  }
  print_digits(number, length, offset);
}

Above code has trouble with select input magnitudes above INT_MAX/10 or so.上面的代码在选择高于INT_MAX/10左右的输入幅度时有问题。 To handle large integers, consider moving to string processing.要处理大整数,请考虑转向字符串处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM