0

I have 4 digit number from 0000 to 1440. I want to generate an equivalent four digit number. That means I can reverse the number from the equivalent number. Basic requirement is the equivalent number must be completely different from the original one. Is there a good equation to do this? For example, each digit can be replaced by 10 - digit. Thus, 1440 becomes 9660, and 1254 becomes 9756.

Thanks.

DigviJay Patil
  • 986
  • 14
  • 31
user3097695
  • 1,152
  • 2
  • 16
  • 42
  • Please edit your question to include some example output for some specified input. Also please show a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) of what you have tried so far, including explanations of how it didn't satisfy your requirements, for example by showing actual and expected output, build errors, runtime errors etc. – Some programmer dude Aug 04 '15 at 01:35
  • How about for each digit n -> (n+1)%10 ? – Beta Aug 04 '15 at 01:36
  • Or indeed `x += 1111`. To reverse it: `x -= 1111` – The Dark Aug 04 '15 at 01:37
  • It is hard to understand your question. However, a simple encoding would be an `XOR cipher` – The Brofessor Aug 04 '15 at 01:38
  • What is "equilavent"? –  Aug 04 '15 at 01:39
  • For example, my original number x and new equilavent number y. My equation is y = F(x) and x = g(y). X and and y must all four digit number. Minor change in x will result completely different y, not simple addition or subtraction. – user3097695 Aug 04 '15 at 01:47
  • So, you are looking for *encryption* and *decryption* algorithms. `x` is *plaintext*, and `y` is *ciphertext*. But still, I can't find a word "equilavent" in any dictionary. –  Aug 04 '15 at 02:10
  • It should be equivalent instead of equilavent. – user3097695 Aug 04 '15 at 02:16
  • I tried the following equation y = 2x + 1357. I do not like it very much. – user3097695 Aug 04 '15 at 02:47

2 Answers2

0

This is, perhaps, more of a comment.

I think your question is rather vague, because you don't define "completely different". Typical "easy" ways are something like:

  • Reverse the number.
  • Substitute the digits for other digits (an easy way is to increment each digit by 1).
  • Substitute pairs of digits for other pairs.

And, you can of course combine these.

In your case, you are starting with a range of 1,441 and mapping to a much larger range (10,000). This actually gives you are larger range of possible mappings.

However, the key point is "how different is different"? You should modify your question to explain that point.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
  • For example, I have a number 1334. Suppose the equivalent is 2445. I have another number 1335, we want its equivalent number to be 4547 or not something purely adding or subtract a number. – user3097695 Aug 04 '15 at 01:45
  • A reverse and substitution is often good enough for visual obfuscation. Not good enough for real encryption, but good enough for some applications. – Gordon Linoff Aug 04 '15 at 01:46
0

You can use a Linear Congruential Generator with a period of 10000. This is a pseudo-random number generator that cycles through each number in the range of 0-9999 once and only once. To generate your number, just take the original number and calculate the next number in the LCG sequence.

An LCG generates random numbers using the following formula:

Xn+1 = ((Xn * a) + c) mod m

To generate 4-digit numbers m should be 10000 (range of 0-9999).

To guarantee no repeats (a "full period") you have to select values for a and c using the following criteria:

c and m are relatively prime

a - 1 is divisible by all prime factors of m

a - 1 is a multiple of 4 if m is a multiple of 4.

The prime factors of 10000 are 2 and 5, and it's also divisible by 4, so any multiple of 20 + 1 will work as a suitable value of a. For c just choose a reasonably large prime number.

e.g: m = 10000, a = 4781, c = 7621

To go the other way, you need to make the function reversible. See this answer for an explanation of the math behind that.

Here's a simple implementation:

#define M (10000)
#define A (4781)
#define C (7621)

int extendedEuclidY(int a, int b);

int extendedEuclidX(int a, int b)
{
    return (b==0) ? 1 : extendedEuclidY(b, a-b*(a/b));
}

int extendedEuclidY(int a, int b)
{
    return (b==0) ? 0 : extendedEuclidX(b, a-b*(a/b)) - (a/b) * extendedEuclidY(b, a-b*(a/b));
}

int forward(int x)
{
   return ((x*A)+C)%M;
}

int backward(int x)
{
   return ((extendedEuclidX(A, M)*(x-C)%M)+M)%M;
}

int main()
{
    int x;
    for(x=0; x<1440; x++)
    {
        printf("%d <-> %d\n", backward(forward(x)), forward(x));
    }
    
    return 0;
}

I've adapted the extendedEuclid functions from the linked answer.

forward(x) finds your equivalent number, backward(x) gets the original back.

Community
  • 1
  • 1
samgak
  • 23,944
  • 4
  • 60
  • 82
  • How do you choose the number M,a and c? I am trying to extend to 6 digits and cannot make it work (M =1000000, a=474581, c= 760021). – user3097695 Aug 16 '16 at 17:21
  • c should be prime (which will ensue M and c are relatively prime as long as M is not a multiple of c). 760021 is not a prime because it is 107 * 7103. Try 760043. You can test for primality with online apps like this one: https://primes.utm.edu/curios/includes/primetest.php – samgak Aug 16 '16 at 22:03
  • Are you having int overflows? You may need to use longs. – samgak Aug 22 '16 at 22:45