Solved

Array value exchanging

Posted on 2006-06-21
17
239 Views
Last Modified: 2010-08-05
I have an array that let user to type in phrases which swap the letters into numbers
for example if user type 'AC350'
the array "num" will store:
num[0] = A
num[1] = C
num[2] = 3
etc...
but the problem is... if i want to convert letters to numbers (e.g. A as 10, C as 12)
what i should write into my program???
cout << "How many digits are there total?\n";
cin  >> digit;
char num[digit];
    cout << "please input all digits.\n";
cin >> num;
Thanks for advance!
0
Comment
Question by:isaac_minovsky
  • 5
  • 2
  • 2
  • +4
17 Comments
 
LVL 3

Expert Comment

by:Dimkov
ID: 16951687
I am not sure what is the difference between "swap the letters into numbers" and "convert letters to numbers "
but I would use
enum MyEnumType { A=10,C=12}

afterwards you might use

array[A]=...

Hope this helps
0
 

Author Comment

by:isaac_minovsky
ID: 16952377
tried it... seems not working...
may be the original code help
#include <math.h>
#include <iostream>
#include <string>
using namespace std;

int main()
{
   
    int base,answer = 0;
    int digit, counter;
    cout << "non 10 radix to decimal converter\nby Issac Minovsky\nversion 1.1.0 6/21/2006\n";
    cout << "What base is the number?";
    cin >> base;
    cout << "How many digits are there total? ";
    cin  >> digit;
    char num[digit];
    cout << "please input all digits in capital letters.\n";
    cin >> num;
    //CONVERTER REQUIRED HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    cout << num[1]; //just tracing the array getting right or not
    answer = 0;
    counter = 0;
    do {
        answer = answer + (num[counter]* (int)pow(base,digit-1));
        digit = digit - 1;
        counter = counter + 1;
        } while (digit > 0);
    cout << "The number in decimal is " << answer <<".\n" ;
    system("PAUSE");
    return EXIT_SUCCESS;
}
0
 
LVL 9

Expert Comment

by:DrAske
ID: 16952567
>>char num[digit];
This is ERROR !! correct it

char* num = new char[digit];

try it ..!!
0
 

Author Comment

by:isaac_minovsky
ID: 16952586
opps... i didn't turn on the ANSI standard...
thx for that...
but the problem is still there...
0
 
LVL 14

Expert Comment

by:wayside
ID: 16952737
try this:

    cin >> num;
    //CONVERTER REQUIRED HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    if (num >= 'A' && num <= 'F') // upper case hex digit
       num = num - 'A' + 10;
    else if (num >= 'a' && num <= 'f') // lower case hex digit
       num = num - 'a' + 10;
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 16953131
The answers of Dimkov and DrAske are wrong.

Wayside's sample works for char's 'A' .. 'F' and 'a' .. 'f' but not for digits. Furthermore, variable 'num' in his sample must be defined as char type.

Here is a full and tested sample code (assuming it isn't a homework question)

#include <string>
#include <iostream>
using namespace std;

enum { MAX_DIGITS = 16 };
int main()
{
  while (true)
  {
    int num[MAX_DIGITS] = { 0 };  // set all 0
    string input;

     cout << "Enter hex number: ";
     cin >> input;
     if (input.length() == 0)
        break;

     for (int i = 0; i < input.length(); ++i)
     {
          if (i >= MAX_DIGITS)
               break;
          char c = input[i];
          if (c >= 'A' && c <= 'F')
              num[i] = c - 'A' + 10;
          else if (c >= 'a' && c <= 'f')
              num[i] = c - 'a' + 10;
          else if (c >= '0' && c <= '9')
              num[i] = c - '0';
          else
              num[i] = -1;  // invalid hex digit
     }

     for (int n = 0; n < input.length(); ++ n)
     {
          if (n >= MAX_DIGITS)
               break;
          cout << num[n] << ' ';
     }
     cout << "    " << input << endl << endl;
  }
  return 0;
}

Regards, Alex

0
 

Author Comment

by:isaac_minovsky
ID: 16954247
Alex,
that's a really good answer... but the code is too perfect that i don't understand....
it seems u are just minus a~f(A~F) and add 10 to num[i]
that code seems only work in hexadecimal to decimal..
what i am trying to do is a encryption program... and i am just using hexadecimal as a experiment....
any more general method...?
may be the code needs to be more flexable that the encryption method can be changed easily
e.g. from a=10,b=11,c=12... to a=1,b=2,c=3...z=26,1=27,2=28...,A=36,B=37...etc.
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 14

Expert Comment

by:wayside
ID: 16954469
It's not entirely clear to me what you are trying to do, but...

characters are already numbers. You don't have to do anything to convert them.

  char num;
  cin >> num;
  cout << (int)num; // cast to int so cout prints it as a number and not a letter

 If you input A this will output 65.
 
 You can also just put it directly into an array:

  char num;
  int numbers[5];
  cin >> num;
  numbers[0] = num;
  cout << numbers[0];

If you input A this will also output 65.

I hope this helps.
0
 
LVL 7

Expert Comment

by:aib_42
ID: 16954526
You should 'parametrize' the hex converter portion to work with an arbitary base. You obviously need to change the limits, 'a' and 'f':

>          else if (c >= 'a' && c <= 'f')
turns into:
else if (c >= 'a' && c <= ('a'+5))

What about base 17?
else if (c >= 'a' && c <= 'g')
turns into
else if (c >= 'a' && c <= ('a'+6))

Base 18 uses a~h and 'h' is ('a'+7), there's a correlation maybe?

Question:
>            num[i] = c - 'a' + 10;
What bases will this portion of the code work with? Does it need to be changed?
0
 

Author Comment

by:isaac_minovsky
ID: 16954530
here is what I did...
#include <string>
#include <math.h>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
   
    int base,c,answer = 0;
    int digit,counter;
    string input;
    cout << "non 10 radix to decimal converter\nby Issac Minovsky\nversion 1.1.0 6/21/2006\n";
    cout << "What base is the number?";
    cin >> base;
    cout << "please input all digits.\n";
    cin >> input;
    const int len = input.length();
    int lencont = input.length();
    int num[len];

    for (int i = 0; i < input.length(); ++i)  
    {  
        char c = input[i];
         switch(num[i])
          {
          case '1':
               num[i] = 1;
               break;
          case '2':
               num[i] = 2;
               break;
          case '3':
               num[i] = 3;
               break;
          case '4':
               num[i] = 4;
               break;
          case '5':
               num[i] = 5;
               break;
          case '6':
               num[i] = 6;
               break;
          case '7':
               num[i] = 7;
               break;
          case '8':
               num[i] = 8;
               break;
          case '9':
               num[i] = 9;
               break;
          case 'A':
               num[i] = 10;
               break;
          case 'B':
               num[i] = 11;
               break;
          case 'C':
               num[i] = 12;
               break;
          case 'D':
               num[i] = 13;
               break;
          case 'E':
               num[i] = 14;
               break;
          case 'F':
               num[i] = 15;
               break;
          }
    }    
   
    cout <<"num 0 = "<< num[0] << "\n";
    cout <<"num 1 = "<< num[1] << "\n";
    cout <<"num 2 = "<< num[2] << "\n";
    cout <<"num 3 = "<< num[3] << "\n";
    cout <<"num 4 = "<< num[4] << "\n";
    answer = 0;
    counter = 0;
    do {
        answer = answer + (num[counter]* (int)pow(base,-1));
        lencont = lencont - 1;
        counter = counter + 1;
        } while (lencont > 0);
    cout << "The number in decimal is " << answer <<".\n" ;
    system("PAUSE");
    return EXIT_SUCCESS;
}

For example, if i change the switch
case '1':
    num[i] = 27;
    break;
case '2':
    num[i] = 28;
    break;
....
case 'a':
    num[i] = 1;
    break;
then the number output will be different...(which means other have to decode it again if they found my old patten)
that's really what i am trying to do... a encrypting program...
in simple word:
to design a software that can code a sentence input by user to special code in a patten, where the patten can be modified easily by designer
0
 

Author Comment

by:isaac_minovsky
ID: 16955462
to aib_42
base chaning is just a prototype for my encrypting program
what i really trying to write is a program that encrypte phrases input by user and swap them  to numbers. (the hex to dec program is just an experiment for the encryption)
may be i should give a better example
'a program that encrypt a as 1, b as 2 ... z as 26, 1 as 27... 9 as 36, 0 as 37 (space as 0)'
so if i input "my name is 123tt"
the output should be "13 25 0 14 1 13 5 0 9 19 0 27 28 29 20 20"
0
 
LVL 3

Accepted Solution

by:
Dimkov earned 25 total points
ID: 16957596
the base is random. and it is the first number in the exported array of numbers. once you have the base key, it is easy to decode the message

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <iostream>
using namespace std;

int main( void )
{
      int i=0;
      srand( (unsigned)time( NULL ) );
      int base=rand();
      char text[100];
      int newText[100];
      cin>>text;
      newText[i]=base;
      while (text[i]!='\0')
      {
            newText[i+1]=text[i]+base;
            i++;
      }
      for (int j=0;j<i+1;j++)
            cout<<newText[j]<<"  ";
}
0
 
LVL 7

Expert Comment

by:nafis_devlpr
ID: 17098719
you can use the following code to convert:

//str is the input string
//num is the encrypted numbr array

char str[1000];
gets(str);
int len=strlen(str), *num=new int[len];
for(int i=0; i < len; i++)
      {
            if(str[i] >= 'A' && str[i] <= 'Z')
                  num[i]=str[i]-'A'+1;
            else if(str[i] >= 'a' && str[i] <= 'z')
                  num[i]=str[i]-'a'+1;
            else if(str[i] >= '1' && str[i] <= '9')
                  num[i]=str[i]-'1'+27;
            else if(str[i] == '0')
                  num[i]=37;
            else if(str[i] == ' ')
                  num[i]=0;
      }
for(i=0; i < len; i++)
      cout << num[i] << " ";
cout << endl;
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 25 total points
ID: 17100715
isaac, the switch you posted actually doesn't change anything:

         switch(num[i])
          {
          case '1':                  // means num[i] == 1
               num[i] = 1;        // ???? it *is* already 1
               break;


nafis, your solution is strange.

The first condition would turn an 'A' to 1 a 'B' to 2, ...,  'Z' to 26  
The second condition would turn an 'a' to 1 a 'b' to 2, ..., 'z' to 26  
The third condition would turn '1' to 27, '2' to 28, ..., '9' to 35
The fourth condition sets '0' to 37
The fifth condition sets all other characters to 0

What is the purpose to convert alpha-numeric characters in that way?

Note, the resulting codes were not printable beside of '7', '8', '9' and '0'. If using input strings that contain special characters such as '-' or '.'  you would not be able to get the input back by decoding.

>>>> but the code is too perfect that i don't understand....
>>>> what i am trying to do is a encryption program... and
>>>> i am just using hexadecimal as a experiment..

isaac, because of the second statement, it makes less sense to explain my solution above in detail cause it simply converts hex digits to integers as it was required in your initial question. If you need encryption hex conversion isn't suitable.

Let's discuss some basics of encryption.

Simple encryption algorithms scramble the input by changing each letter to another one, e. g. 'A' to 'F', 'B' to 'M', 'C' to 'H', ...

Note, if you want to decode the scrambled string back to the original you never could assign the same letter to different letters, e. g. if 'A' -> 'F' you can't make 'K' -> 'F'. To achieve that you need to make a permutation of the original character set. A simple permutation you can get by adding an offset number to all letters, e. g. +5, waht turns 'A' to 'F', 'B' to 'G', 'C' to 'H' and so on. Obviously, we need to care for 'V', 'W', 'X', 'Y', 'Z' taht need to get mapped to 'A' to 'E' accordingly:

      for (int i = 0; i < input.length(); ++i)
      {
            if (input[i] >= 'A' && input[i] <= 'Z')
            {
                   output[i] = ((input[i] + 5) - 'A') % 26) + 'A';
            }
      }

Let's check the algorithm for char 'X'.

     ('X' + 5)                            == 88 + 5 == 93
     ('X' + 5) - 'A'                     == 93 - 65 == 28
    ( ('X' + 5) - 'A') % 26)         == 28 % 26 == 2
    ( ('X' + 5) - 'A') % 26) + 'A'  == 2 + 65 == 67 == 'C'


Seems ok.

Though the encryption is stupid simple, it has some flaws.

1. What to do with small letters ?

You simply can add the same algorithm for small letters:

           if (input[i] >= 'A' && input[i] <= 'Z')
            {
                   output[i] = (((input[i] + 5) - 'A') % 26) + 'A';
            }
           else if (input[i] >= 'a' && input[i] <= 'z')
            {
                   output[i] = (((input[i] + 5) - 'a') % 26) + 'a';
            }

So, capital letters keep capital letters and small letters keep small letters

2. Digits?

           ...
            else if (input[i] >= '0' && input[i] <= '0')
            {
                   output[i] = (((input[i] + 5) - '0') % 10) + '0';
            }
 
Note, there are only 10 digits.

3. Non-alphanumerics?

Now it gets difficult.

Let's deal with ASCII letters first. ASCII are the codes from 0 to 127 where 0 to 31 and 127 are not printable (and most probably are not in your input string). The problem is that if we already handled letters and digits like above, we cannot handle the rest of special characters same way cause the codes were in different ranges. We have special characters from 32 (space) to 47 ('/'), from 58 (':') to 64 ('@') and from 123 ('{') to 126 ('~').

           ...
            else if (input[i] >= ' ' && input[i] <= '/')
            {
                   output[i] = (((input[i] + 5) - ' ') % ('/' - ' ' + 1) ) + ' ';
            }
            else if (input[i] >= ':' && input[i] <= '@')
            {
                   output[i] = (((input[i] + 5) - ':') % ('@' - ':' + 1)) + ':';
            }
            else if (input[i] >= '{' && input[i] <= '~')
            {
                   output[i] = (((input[i] + 5) - '{') % ('~' - '{' + 1 ) ) + '{';
            }

Note, rather than to count the number of each range I computed it by subtracting the minimum from the maximum char.

4. Non-printables or extended ANSI characters?

Non-printable characters (range 0 ... 31) can't be entered via keyboard beside of a few exceptions (Tab == 9, Linefeed = 10). Even these won't be stored when using normal console input. So, it is good practice to ignore non-printables for encrypting.

The ANSI char set from 128 to 255 contains some special characters such as '²', 'ä', ...

The problem is that some of them are not printable if not using the appropriate codepage or the appropriate printer. So, principially we could adopt our solution from above, but if you try to print out the encoded string you may see only rubbish.

            ...
            else if ((unsigned char)input[i] >= (unsigned char)128 &&
                       (unsigned char)input[i] <= (unsigned char)255)
            {
                   int c = input[i];
                   output[i] = (char)((((c + 5) - 128) % 128) ) + '0');
            }

Note, I have to consider that char is signed char in the range of -128 to +127 what means that all ANSI char have a negative integer number. To get around that I converted to 'unsigned char' for comparing and took an 'int' for the calculations to not get fooled by negative numbers.

To make the encoding reverse, you simply could take the same algorithm but subtract 5 rather than add it.

With that you should get a scrambled input which cannot easily get decoded by a human being, especially if you keep the offset (5 in the sample) secret. However, for a program or a professional the coding is ridiculous. It is cracked within seconds, especially if the cracker could try some inputs and compare the outputs.

If that is a problem for you, I can give you some better algorithms or you are using a professional encoding library which can make the encrypting absolutely safe with some efforts.

Regards, Alex


 
         




0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now