Thread: Could someone explain the Logic for this binary to ascii code please?

  1. #1
    Registered User
    Join Date
    Oct 2011
    Posts
    33

    Could someone explain the Logic for this binary to ascii code please?

    Hi folks

    I was browsing through the C program threads and I came across a binary to ascii code (something my professor recently showed a very brief example on)

    This code is a lot more complex than what my professor had showed us and I'm really interested in finding out what it's doing. The main was provided and the objective was to build a function. There are no comments so i dont have much of an idea as to what is going on, I did copy n paste the program into my editor to run it and see what it does.

    all I understood from the main is there are:
    A string of binary codes with some being mixed with special characters to produce an ascii number that will print a letter.
    There are 5 sections separated by commas (i think that's what's separating them)
    In the end there will be a blank line followed by uh...sentences?

    The original code was posted by user: BigMac(Rexdale)

    This is the main
    Code:
    #include <stdlib.h>#include <stdio.h> #include <string.h> #include <ctype.h> #define LINES 5 /* assignment #1 function prototype */ int bit_to_ascii(const char [ ], char [ ]); int main( ) { const char *core_data[ ] = { "0", /* should insert the null byte '\0' only */ "01010111 This sequence contains the letter 'W' " /* 87 = 'W' */ " r5 0 #! 1 1 gP 0 f66-:] 0 [ } 1 v4t^ 0 1 n>?:77" /* 101 = 'e' */ " junk ^*@&#^% 0110 more junk }{r;,<> 1100 2x" /* 108 = 'l' */ " 0 1 1 0 0 011" /* 99 = 'c' */ "0 ^%jh 1 ]{) OVR 1 - 0 _! 9 + 1 118Y z(x pM1 " /* 111 = 'o' */ "This next group of 8 should be SKP skipped! 11111111 " /* skipped */ "*&^! 0 1 1 0 1 1 0 128673kjshd:L< 2938 " /* 109 = 'm' */ " r5 0 #! 1 1 gP 0 f66-:] 0 [ } 1 v4t^ 0 1 n>?:77" /* 101 = 'e' */ "#!/bin/bash 00 1 00 00 0 g^b-ps 6@&^% " /* 32 = ' ' */ "01010100 This sequence contains the letter 'T' " /* 84 = 'T' */ "0 ^%jh 1 ]{) OVR 1 - 0 _! 9 + 1 118Y z(x pM1 " /* 111 = 'o' */ "#!/bin/bash 00 1 00 00 0 g^b-ps 6@&^% " /* 32 = ' ' */ "---repeat--->0 1 0 0 1 1 1 1<------------RPT2--------" /* 79 = 'O' */ "0 1 0 1 0bbavac9872962 000&*************************" /* 80 = 'P' */ "a0b0c1d1e0f0g1h0ijklmnopqrstuvwxyz*******************" /* 50 = '2' */ "00fg333 110100>>>>>>>>" /* 52 = '4' */ "00fg333 110100>>>>>>>>" /* 52 = '4' */ " 0000 ",/* 0 = '\0' */ "00011110 This char should not be inserted! " /* 30 cntrl */ " 00011111 This char should not be inserted! " /* 31 cntrl */ " 00100000 " /* 32 = ' ' */ " 00100001 " /* 33 = '!' */ " 00100010 " /* 34 = '"' */ " 00100011 " /* 35 = '#' */ " 00100100 " /* 36 = '$' */ " 00100101 " /* 37 = '%' */ " 00100110 " /* 38 = '&' */ " 00100111 " /* 39 = ''' */ " 00101000 " /* 40 = '(' */ " 00101001 " /* 41 = ')' */ " 00101010 " /* 42 = '*' */ " 00101011 " /* 43 = '+' */ " 00101100 " /* 44 = ',' */ " 00101101 " /* 45 = '-' */ " 00101110 " /* 46 = '.' */ " 00101111 " /* 47 = '/' */ " 00110000 " /* 48 = '0' */ " 00110001 " /* 49 = '1' */ " 00110010 " /* 50 = '2' */ " 00110011 " /* 51 = '3' */ " 00110100 " /* 52 = '4' */ " 00110101 " /* 53 = '5' */ " 00110110 " /* 54 = '6' */ " 00110111 " /* 55 = '7' */ " 00111000 " /* 56 = '8' */ " 00111001 " /* 57 = '9' */ " 00111010 " /* 58 = ':' */ " 00111011 " /* 59 = ';' */ " 00111100 " /* 60 = '<' */ " 00111101 " /* 61 = '=' */ " 00111110 " /* 62 = '>' */ " 00111111 " /* 63 = '?' */ " 01000000 " /* 64 = '@' */ " 00000000 ",/* 0 = '\0'*/ " 01000001 " /* 65 = 'A' */ " 01000010 " /* 66 = 'B' */ " 01000011 " /* 67 = 'C' */ " 01000100 " /* 68 = 'D' */ " 01000101 " /* 69 = 'E' */ " 01000110 " /* 70 = 'F' */ " 01000111 " /* 71 = 'G' */ " 01001000 " /* 72 = 'H' */ " 01001001 " /* 73 = 'I' */ " 01001010" /* 74 = 'J' */ " 01001011 " /* 75 = 'K' */ " 01001100 " /* 76 = 'L' */ " 01001101 " /* 77 = 'M' */ " 01001110 " /* 78 = 'N' */ " 01001111 " /* 79 = 'O' */ " 01010000 " /* 80 = 'P' */ " 01010001 " /* 81 = 'Q' */ " 01010010 " /* 82 = 'R' */ " 01010011 " /* 83 = 'S' */ " 01010100 " /* 84 = 'T' */ " 01010101 " /* 85 = 'U' */ " 01010110 " /* 86 = 'V' */ " 01010111 " /* 87 = 'W' */ " 01011000 " /* 88 = 'X' */ " 01011001 " /* 89 = 'Y' */ " 01011010 " /* 90 = 'Z' */ " 01011011 " /* 91 = '[' */ " 01011100 " /* 92 = '\' */ " 01011101 " /* 93 = ']' */ " 01011110 " /* 94 = '^' */ " 01011111 " /* 95 = '_' */ " 01100000 " /* 96 = '`' */ " 00000000 ",/* 0 = '\0'*/ " 01100001 " /* 97 = 'a' */ " 01100010 " /* 98 = 'b' */ " 01100011 " /* 99 = 'c' */ " 01100100 " /* 100 = 'd' */ " 01100101 " /* 101 = 'e' */ " 01100110 " /* 102 = 'f' */ " 01100111 " /* 103 = 'g' */ " 01101000 " /* 104 = 'h' */ " 01101001 " /* 105 = 'i' */ " 01101010 " /* 106 = 'j' */ " 01101011 " /* 107 = 'k' */ " 01101100 " /* 108 = 'l' */ " 01101101 " /* 109 = 'm' */ " 01101110 " /* 110 = 'n' */ " 01101111 " /* 111 = 'o' */ " 01110000 " /* 112 = 'p' */ " 01110001 " /* 113 = 'q' */ " 01110010 " /* 114 = 'r' */ " 01110011 " /* 115 = 's' */ " 01110100 " /* 116 = 't' */ " 01110101 " /* 117 = 'u' */ "01110110 " /* 118 = 'v' */ " 01110111 " /* 119 = 'w' */ " 01111000 " /* 120 = 'x' */ " 01111001 " /* 121 = 'y' */ " 01111010 " /* 122 = 'z' */ " 01111011 " /* 123 = '{' */ " 011111RPT10 " /* 124 = '|' */ " 01111101 " /* 125 = '}' */ " 00000000 " /* 0 = '\0'*/ }; char phrase[41]; char correct[LINES][41] = { "", "Welcome To OOP244", " !\"#$%&'()*+,-./0123456789:;<=>?@", "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`", "abcdefghijklmnopqrstuvwxyz{||||||||||}" }; int rvalues[LINES] = { 1, 18, 34, 33, 39 }, i; int valid = 1, rc, err_code; for(i=0; i<LINES && valid; i++) { rc = bit_to_ascii(core_data[i], phrase); if(rc != rvalues[i] || strcmp(phrase, correct[i])) { printf("Failed on test... %d\n\n", i+1); valid = 0; } else { printf("Passed test %d...\n\n", i+1); } printf("Your string ----------> '%s'\n", phrase); printf("Actual string --------> '%s'\n", correct[i]); printf("Your return value ----> %d\n", rc); printf("Actual return value --> %d\n", rvalues[i]); printf("Press the ENTER key to continue..."); getchar( ); } if(valid) { printf("\nCongratulations!!! You passed all tests.\n"); printf("You may hand in your assignment.\n"); } else { printf("\nYou correctly sequenced %d/5 data blocks...\n", i-1); printf("Your program still needs some work!\n"); printf("Keep at it!\n\n"); } return 0; }

    and a clean solution was provided by user: Arpsmack
    and what i think i understood from the function is:

    char input and output cannot change, they are constants
    (i believe that's what const is for)
    value is representing the ascii values and has been assigned a value of zero
    num_bits i think represents the number of bits which should be 8
    and repeat...i dont know why repeat is there for.
    isdigit is checking the string for a number
    isprint is checking for a printable character (not quite sure what that is, i looked it up)
    I dont understand what skip is being used for (is that a ctype function?)
    the 5 sections of the code has been separated into cases 0, 1, S, R and S for the skip section, R for the repeat.


    now the issue im having is, what is actually happening in each case?

    Code:
    intbit_to_ascii(constcharinput[], charoutput[]) {
    const char *src = input; char *dst = output; int value = 0; int num_bits = 0; int repeat = 1; while (*src != '\0') { switch (*src++) { case '0': value += value; num_bits++; break; case '1': value += value + 1; num_bits++; break; case 'S': if (src[0] == 'K' && src[1] == 'P') { int skip = 8; while (skip > 0) { if (*src == '0' || *src == '1') skip--; src++; } } break; case 'R': if (src[0] == 'P' && src[1] == 'T') { src += 2; repeat = 0; while (isdigit(*src)) repeat = (repeat * 10) + (*src++ - '0'); if (num_bits == 0) { char last = *(dst - 1); for (repeat; repeat > 1; repeat--) *dst++ = last; } else while (num_bits < 8) { value <<= 1; num_bits++; } } break; } if (num_bits > 7) { if (isprint(value) || value == 0) for (repeat++; repeat > 1; repeat--) *dst++ = (char)value; num_bits = 0; value = 0; } } if (num_bits > 0 && (isprint(value) || value == 0)) *dst++ = value; return (int)(dst - output); }

    When I asked my professor more details on her example she said I could find more information on the web---and then she recommended me to come here (i have for some time).


    I was going to ask this question in the original thread but i always get flamed for posting in old/dead threads

    heres the original if anyone wanted to see it :

    C Program logic error?



    I appreciate any help I can get.

  2. #2
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Create a function that decodes an array of length 8 with 1s and 0s to a character.

    Then create a function that decodes an array of any length in multiples of 8, by iterating it 8 steps at a time, in each iteration you call the first function with the next 8 bits.

    Shouldn't take more than 20 lines of code or so to do, for both functions.

  3. #3
    Registered User
    Join Date
    Oct 2011
    Posts
    33
    Quote Originally Posted by Subsonics View Post
    Create a function that decodes an array of length 8 with 1s and 0s to a character.

    Then create a function that decodes an array of any length in multiples of 8, by iterating it 8 steps at a time, in each iteration you call the first function with the next 8 bits.

    Shouldn't take more than 20 lines of code or so to do, for both functions.
    ah that makes perfect sense

    however, what is this skip and repeat for?

    Code:
    int skip = 8;
    while (skip > 0) {
    if (*src == '0' || *src == '1')
    skip--;
    src++;

    Code:
    repeat = 0;
    while (isdigit(*src))
    repeat = (repeat * 10) + (*src++ - '0');
    i saw near the end of the strings, number 124, it says

    011111RPT10

    is that repeat 10 times, if it is, for what? and then src++ is increased...then subtracted by zero?...I dont get what the purpose of that is.

  4. #4
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by ShadowBoss View Post
    ah that makes perfect sense

    however, what is this skip and repeat for?
    It was not a comment on the code, my point was that it's probably not the best example you could find.

    You could do like this as well for example.

    Code:
    char decode_char(char *bin_string) {
        uint8_t mask = 0x80;
        char c = 0;
    
        for(int i = 0; i < 8; i++) {
            if(bin_string[i] == '1') {
                c += mask;
            }
            mask >>= 1;
        }
        return c;
    }
    
    void decode_string(char *bin_string) {
        int len = strlen(bin_string);
        if(len % 8) return;
    
        for(int i = 0; i < len; i += 8) {
            char c = decode_char(bin_string + i);
            putchar(c);
        }
        puts("");
    }

  5. #5
    Registered User
    Join Date
    May 2012
    Posts
    505
    The professor is giving you a strign consisting of 1s and 0s interpsersed with garbage. You've got to divide the 1s and 0s into blocks of 8, and translate to ascii. In addition there seems to be a special case that nul is any number of 0s, and there are two fiddly rules involving the sequences RPT and SKP.

    So, ignoring the fiddly bits, we've got to step throught the string. If we get a 1 or a 0, we add it to value. When we reach 8 1s or 0s, we have a full ascii character, and so we write it to the output string.


    First fiddly bit - if a value isn't a valid ascii character, don't insert it.
    Second fiddly bit - if the string ends before ypu've read 8 zeros into the nul, treat it as if it was a proper nul.
    Third fiddly bit - SKP means skip the next 8 1s and 0s.
    Fourth fiddly bit - RPT means repeat the preceding sequence N times, unless N contains the digits 1 or 0, in which case they are added to the sequence to repeat. (This last rule seems pretty odd, so in a real situation ypu'd have to get clarification for this specification).

  6. #6
    Registered User
    Join Date
    Oct 2011
    Posts
    33
    Quote Originally Posted by Malcolm McLean View Post
    The professor is giving you a strign consisting of 1s and 0s interpsersed with garbage. You've got to divide the 1s and 0s into blocks of 8, and translate to ascii. In addition there seems to be a special case that nul is any number of 0s, and there are two fiddly rules involving the sequences RPT and SKP.

    So, ignoring the fiddly bits, we've got to step throught the string. If we get a 1 or a 0, we add it to value. When we reach 8 1s or 0s, we have a full ascii character, and so we write it to the output string.


    First fiddly bit - if a value isn't a valid ascii character, don't insert it.
    Second fiddly bit - if the string ends before ypu've read 8 zeros into the nul, treat it as if it was a proper nul.
    Third fiddly bit - SKP means skip the next 8 1s and 0s.
    Fourth fiddly bit - RPT means repeat the preceding sequence N times, unless N contains the digits 1 or 0, in which case they are added to the sequence to repeat. (This last rule seems pretty odd, so in a real situation ypu'd have to get clarification for this specification).
    Okay it's starting to make more sense as to what is going on with both codes, thank you very much guys, at least if this pops up on a test i'll have an idea of how to go about it.

    @Subsonics that's really condensed wow lol. How come you don't use a constant? Would a constant even be necessary in for a program like this?

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by ShadowBoss View Post
    @Subsonics that's really condensed wow lol. How come you don't use a constant? Would a constant even be necessary in for a program like this?
    It really isn't that condensed IMO, sure there is no error handling for the binary strings format, but the idea was to have the parts that shows the concept only. What constant are you referring to?

  8. #8
    Registered User
    Join Date
    Oct 2011
    Posts
    33
    like here it says :

    Code:
    intbit_to_ascii(constcharinput[], charoutput[]) {
    const char *src = input;




    Why is that placed as a const char *src?

  9. #9
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by ShadowBoss View Post
    like here it says :

    Code:
    int bit_to_ascii(const char input[], char output[]) {
    const char *src = input;




    Why is that placed as a const char *src?
    Well in the example you provided the function prototype is declared to take a const input parameter, which is followed through to the assignment of input to src. This is necessary to respect the const, if you look at the argument passed to the function, it's an strings array, also declared const.

  10. #10
    Registered User
    Join Date
    Oct 2011
    Posts
    33
    but why use const at all? what benefit would it have in this case?

  11. #11
    Registered User
    Join Date
    Oct 2011
    Posts
    33
    Hey folks, i have another question, I ran the code and it works but I wanted to change some stuff to see what would happen


    Code:
    switch (*src++) {
    case '0':
    value += value; num_bits++;
    break;
    case '1':
    value += value + 1; num_bits++;
    break;
    case 'S':
    if (src[0] == 'K' && src[1] == 'P') {
    int skip = 8;
    while (skip > 0) {
    if (*src == '0' || *src == '1')
    skip--;
    src++;
    }
    }
    break;
    case 'R':
    if (src[0] == 'P' && src[1] == 'T') {
    src += 2;
    repeat = 0;
    while (isdigit(*src))
    repeat = (repeat * 10) + (*src++ - '0');
    if (num_bits == 0) {
    char last = *(dst - 1);
    for (repeat; repeat > 1; repeat--)
    *dst++ = last;
    }
    else
    while (num_bits < 8) {
    value <<= 1;
    num_bits++;
    }
    }
    break;


    I changed the each case variables(?) individually to something else and ran it and they didn't run except for case S

    example:

    Case '0' --> Case 'A' failed
    Case '1' --> Case 'F' failed
    Case 'S' --> Case 'X' passed
    Case 'R' --> Case 'E' failed

    so what i did was change one case variable then run it if it failed id change it back and then change the next case and run it etc.

    Why is it that case S was not affected but the rest were?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can someone explain the logic of the program
    By chibi.coder in forum C Programming
    Replies: 5
    Last Post: 12-25-2011, 09:23 AM
  2. Replies: 2
    Last Post: 10-14-2009, 07:45 AM
  3. ASCII to Binary and Hex
    By Korhedron in forum C++ Programming
    Replies: 8
    Last Post: 07-28-2003, 09:31 AM
  4. Logic behind Binary Search?
    By aspand in forum C Programming
    Replies: 3
    Last Post: 05-21-2002, 10:46 AM
  5. binary to ascii
    By ygfperson in forum C++ Programming
    Replies: 2
    Last Post: 04-20-2002, 08:36 AM