Hey guys I'm having an extremely hard time splitting or combining values into binary..

#define Chr(n) ((char)(n))
#define Ord(c) ((int)(unsigned char)(c))

int DecToBin(int Num)
{
    int Bin = 0, Pos = 1;
    while (Num > 0)
    {
      Bin += (Num % 2) * Pos;
      Num /= 2;
      Pos *= 10;
    }
    return Bin;
}

int ConcatIntegers(IntegerArray Integers)
{
    stringstream SS;
    for (unsigned short I = 0; I < Integers.size(); I++)
    {
        SS<<Integers[I];
    }
    assert(SS.str().size() <= 10);
    return strtol(SS.str().c_str(), NULL, 10);
}

string EncodeB64(string StringToEncode)
{
    size_t STE_Size = StringToEncode.size();
    IntegerArray Binaries;            //Custom time.. just a vector of ints

    for (unsigned short I = 0; I < STE_Size; I++)
        Binaries(DecToBin(Ord(StringToEncode[I])));

    //Binaries now holds an array of Binary Integers..
    //Example.. Binaries looks like:  [10101011, 101010011, 10010101...]
    //For each letter in the string..
}

I've been following: http://www.cpp-home.com/tutorials/102_1.htm

And it says Convert each character in the string to binary.. which I did above. Then it says to connect all the characters into one.. That is a problem for me because if it's an entire sentence, an integer isn't large enough to hold even 3 sets of those..

Example.. I'm trying to do the above into: 1010101110101001110010101... using ConcatIntegers function but it overflows.. I'm thinking of making it all into a string and then splitting it into 6 like the tutorial says and then convert each one back to an ASCII character and continue from there but that's quite tedious..

Any better Ideas? I do not want any copyright stuff.. I wanted to write my own so I learn something AND I won't have to copy anyone else's..

Edited 4 Years Ago by triumphost: n/a

To get it right you need to pad the binary numbers out to 8 so when you group them by 6 you get the right answer

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

#define Ord(c) ((int)(unsigned char)(c))

string DecToBin(int Num){
    int Bin = 0, Pos = 1;
    stringstream SS;
    while (Num > 0){
      Bin += (Num % 2) * Pos;
      Num /= 2;
      Pos *= 10;
    }
    SS.fill('0'); 
    SS.width(8);
    SS << Bin;
    return SS.str();
}
string BinToDec(string s){
  int ret(0),pos(0);
  string::reverse_iterator rit;
  for ( rit=s.rbegin() ; rit < s.rend(); rit++,pos++ ){
     if (*rit == '1'){
         // Beware that 2^pos doesn't get larger than 2^31
         // but this would only happen if you went to a base
         // of 31 or greater
         ret += 1 << pos;
     }
  }
  stringstream SS;
  SS << ret << " ";
  return SS.str();
}
string EncodeB64(string StringToEncode){
    size_t STE_Size = StringToEncode.size();
    string bin,ret;
    for (unsigned short I = 0; I < STE_Size; I++)
        bin += DecToBin(Ord(StringToEncode[I]));

    //Binaries now holds an array of Binary Integers..
    //For each letter in the string..
    while( bin.size() ) {
       ret += BinToDec(bin.substr(0,6));
       bin.erase(0,6);
    }
    return ret; 
}

int main(){
    string encryptStr("Hello");
    string encryptBin(EncodeB64(encryptStr));
    cout << "\"" << encryptStr << "\" encrypted -> " << encryptBin << endl;    
    return 0;
}

Output:

$ ./a.out
"Hello" encrypted -> 18 6 21 44 27 6 15

Edited 4 Years Ago by histrungalot: Removed pow function

Hmm I've tried your solution and suggestions.. but when I actually convert it back to the letters either manually with pen and paper or with code.. it gives the wrong ones..

I think it might be the splitting into groups of 6.

Both of these print the same thing except that the last character is always wrong. I have no clue how to pad the equal sign onto the bytes.. I tried

if ((StringToEncode.size() % 3) == 1)
{
result += "=";
}

string EncodeB64(string StringToEncode)
{
    const string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    size_t STE_Size = StringToEncode.size();
    StringArray Binaries;

    for (unsigned short I = 0; I < STE_Size; I++)
        Binaries(DecToBinStr(Ord(StringToEncode[I]), 8));

    Binaries = SplitString(ConcatStrArrayToStr(Binaries), 6);

    for (int I = 0; I < Binaries.size(); I++)
    {
        Binaries[I] = BinToDec(Binaries[I]);
    }
    string Result;
    for (int I = 0; I < StringArrayToIntArray(Binaries).size(); I++)
        Result += base64_chars[StringArrayToIntArray(Binaries)[I]];
    return Result;
}
string EncodeB64X(string StringToEncode)
{
    size_t STE_Size = StringToEncode.size();
    string bin,ret;
    for (unsigned short I = 0; I < STE_Size; I++)
        bin += DecToBinStr(Ord(StringToEncode[I]), 8);

    while(bin.size())
    {
       ret += BinToDec(bin.substr(0,6));
       bin.erase(0,6);
    }
    return ret;
}

How is StringArrayToIntArray(Binaries) turning the strings into ints? Wht is the example that '=' is causing an issue?

Edited 4 Years Ago by histrungalot: n/a

The = is for both.. Neither of the functions above print the last character correctly. apparently if the bytes aren't divisible by 3, I'm supposed to pad it with an = sign or something which I have no clue how to do..

Both of our functions print the same values.

These are the functions I used:

StringArray SplitString(string StrToSplit, int NumberOfPieces)
{
    string Temp = StrToSplit;
    StringArray Result;
    while(Temp.size())
    {
       Result(Temp.substr(0, NumberOfPieces));
       Temp.erase(0, NumberOfPieces);
    }
    return Result;
}

string ConcatStrArrayToStr(StringArray Strings, string Delimiter = "")
{
    stringstream SS;
    for (unsigned short I = 0; I < Strings.size() - 1; I++)
        SS<<Strings[I]<<Delimiter;

    SS<<Strings[Strings.size() - 1];
    return SS.str();
}

IntegerArray StringArrayToIntArray(StringArray StrArrayToConvert)
{
    IntegerArray Result;
    Result.SetLength(StrArrayToConvert.size());
    for (int I = 0; I < StrArrayToConvert.size(); I++)
    {
        Result[I] = strtol(StrArrayToConvert[I].c_str(), NULL, 10);
    }
    return Result;
}

Edited 4 Years Ago by triumphost: n/a

I may have gone to far off the path but maybe this will still help you.

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

const string base64_chars("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");

#define Chr(n) ((char)(n))
#define Ord(c) ((int)(unsigned char)(c))

string DecToBinStr(int Num, int pad=0){
   stringstream SS;
   string tmp;
   while(Num>0){
     if ( Num&1 )
        tmp = "1" + tmp;
     else
        tmp = "0" + tmp;
     Num >>= 1;
   }
   if ( pad ) {
       SS.fill('0');
       SS.width(pad);
   }
   SS << tmp;
   return SS.str();
}

int BinToDec(string s){
  int ret(0),pos(0);
  string::reverse_iterator rit;
  for ( rit=s.rbegin() ; rit < s.rend(); rit++,pos++ ){
     if (*rit == '1'){
         // Beware that 2^pos doesn't get larger than 2^31
         // but this would only happen if you went to a base
         // of 31 or greater
         ret += 1 << pos;
     }
  }
  return ret;
}

string BinToDecStr(string s){
  int ret(0),pos(0);
  string str;
  string::reverse_iterator rit;
  for ( rit=s.rbegin() ; rit < s.rend(); rit++,pos++ ){
     if (*rit == '1'){
         // Beware that 2^pos doesn't get larger than 2^31
         // but this would only happen if you went to a base
         // of 31 or greater
         ret += 1 << pos;
     }
  }
  str.assign(1,Chr(ret));
  return str;
}

string BinToChr(string s){
  string ret;
  ret.assign(1,Chr(BinToDec(s)));
  return ret;
}

string EncodeB64(string StringToEncode) {
    size_t STE_Size = StringToEncode.size();
    string bin,ret;
    for (unsigned short I = 0; I < STE_Size; I++)
        bin += DecToBinStr(Ord(StringToEncode[I]), 8);
    while(bin.size()) {
       ret += base64_chars[BinToDec(bin.substr(0,6))];
       bin.erase(0,6);
    }
    return ret;
}
string DeEncodeB64(string StringToEncode){
    size_t STE_Size = StringToEncode.size();
    string bin,ret;
    for (int i(0); i < STE_Size-1; i++)
        bin += DecToBinStr(base64_chars.find(StringToEncode[i]),6);
    bin += DecToBinStr(base64_chars.find(StringToEncode[STE_Size-1]),8-((STE_Size-1)*6)%8);
    //Binaries now holds an array of Binary Integers..
    //For each letter in the string..
    while( bin.size() ) {
       ret += BinToChr(bin.substr(0,8));
       bin.erase(0,8);
    }
    return ret;
}

string EncodeB64X(string StringToEncode) {
    size_t STE_Size = StringToEncode.size();
    string bin,ret;
    for (unsigned short I = 0; I < STE_Size; I++)
        bin += DecToBinStr(Ord(StringToEncode[I]), 8);
    while(bin.size()) {
       ret += BinToDecStr(bin.substr(0,6));
       bin.erase(0,6);
    }
    return ret;
}
string DeEncodeB64X(string StringToEncode){
    size_t STE_Size = StringToEncode.size();
    string bin,ret;
    for (int i(0); i < STE_Size-1; i++)
        bin += DecToBinStr(Ord(StringToEncode[i]),6);
    bin += DecToBinStr(Ord(StringToEncode[STE_Size-1]),8-((STE_Size-1)*6)%8);
    //Binaries now holds an array of Binary Integers..
    //For each letter in the string..
    while( bin.size() ) {
       ret += BinToChr(bin.substr(0,8));
       bin.erase(0,8);
    }
    return ret;
}

int main(){
    // Set encryption string
    string encryptStr("Working!");
    // Encrypt string
    string encryptBin(EncodeB64X(encryptStr));
    // Print results
    cout << encryptStr << " -> EncodeB64X -> ";
    for (int i(0); i < encryptBin.size(); i++)
       cout << int(encryptBin[i]) << " ";
    cout << " -> DeEncodeB64X -> " << DeEncodeB64X(encryptBin) << endl;
    // Do it the other way
    encryptBin = EncodeB64(encryptStr);
    cout << encryptStr << " -> EncodeB64 -> " << encryptBin
         << " -> DeEncodeB64 -> " << DeEncodeB64(encryptBin) << endl;
    return 0;
}

Output:

$ ./a.out
Working! -> EncodeB64X -> 21 54 61 50 26 54 37 46 25 50 1  -> DeEncodeB64X -> Working!
Working! -> EncodeB64 -> V29ya2luZyB -> DeEncodeB64 -> Working!
$
Comments
Absolutely Brilliant.. I edited it to work with my stringarray and shortened it a bit. Thanks!!
This question has already been answered. Start a new discussion instead.