0

Thanks, well as of the language, I wasn't that specific as I knew the solutions maybe on C++, C#, as also the complete system is written in different languages because some other languages provide even more powerful features, like how I protect a visual digital media (Video) I used C++ for this as I've got a very powerful system which I used to prevent it from being copied via Screen recoders, video recoder cameras.

Thanks I will try to pla around with both solutions provided and see.
@NULL, there is no way of mixing the frames around since as you have stated on your above post that using CRC or corrupting it by writing 1 will cause those players that don't play a media with bad CRC, but the problem is that there maybe those that plays it anyway without checking if its bad or not. So my thought is, if its possible to change around the frames as in chunks or blocks and swop them around.

The reason for this is that I also don't want converters to be able to convert this file to an MP3 file they also must not recorgize this file as well because if they do, then the whole project or system is a loss.

0

Also just a quick add on, by writing to H I wasn't corrupting the file but was storing the key to tell how to correct the file as I've stated on the other post where I also had a formular but then since I can't write more that 1, I've thought of also complying with that bit rule of either write 0 or 1, but now this is for another part now which doesn't relate to file playback or surppot of its playing as I also look at other options of corrupting this file, which some of the options as you have stated of playing around with D, M.

0

What do those tags refer to?

I presume those are tag "suggestions" in that if you want to add tags to an existing thread you can just click on those. Yes. It's confusing. The only tags actually associated with a thread are displayed on the thread summary page.

0

Mr. M,

I'm not sure my response to your PM was successfully delivered, so I'm posting this in the thread itself, which is the preferred way anyway. To everyone else, Mr. M asked me to elaborate on the method in my program above in this thread, so I changed the program around a little to make it a little more generic and added a bit of explanation below.

"Hello World" is 12 characters long (5 for "Hello", 1 for space between words, 5 for "World", 1 for NULL terminator, 5 + 1 + 5 + 1 = 12. Each character is 8 bits, so 'H' is bits 0 through 7 and 'e' is bits 8 through 15. 'e' is the character that I was changing in the example by changing the 13th bit. The ASCII value of 'e' is 101 in base 10. The ASCII value of 'a' is 97. See this chart.

http://www.asciitable.com/

To make it clearer which bits I am referring to, in the manipulations below, I will surround the most significant bit (bit 8) in brackets []. I will put the 13th bit in parentheses (). I will put the least significant bit (bit 15) in these brackets {}. Flipping the 13th bit from 1 to 0 and back again is done as below.

[0]1100(1)0{1}   // this is 'e', which is 101 in decimal, 01100101 in base 2, the 13th bit is 1, which is in parentheses. "Hello World"
[0]1100(0)0{1}   // this is 'a', which is 97 in decimal, 01100001 in base 2, the 13th bit is now 0, which is in parentheses. "Hallo World"
[0]1100(1)0{1}   // this is 'e' again, which is 101 in decimal, 01100101 in base 2, the 13th bit is 1, which is in parentheses. "Hello World"

Note that flipping that bit results in changing the value by the byte by 4 each time you do it. If we flip the 14th bit instead of the 13th bit, this will change the value by 2 instead of 4, so it will change from 'e' to 'g' and back (note I made a mistake in the original post in the thread, saying it would switch between 'e' and 'c'. It actually switches between 'e' and 'g' for the 14th bit).

[0]11001(0){1}   // this is 'e', which is 101 in decimal, 01100101 in base 2, the 14th bit is 0, which is in parentheses. "Hello World"
[0]11001(1){1}   // this is 'g', which is 103 in decimal, 01100111 in base 2, the 14th bit is now 1, which is in parentheses. "Hgllo World"
[0]11001(0){1}   // this is 'e', which is 101 in decimal, 01100101 in base 2, the 14th bit is 0, which is in parentheses. "Hello World"

Try this new updated program. You can enter any phrase and bit number and see what happens. Note that not all values will be printable. See the ASCII table. Any value above 127 won't print probably, and some of the values between 0 and 127 don't print either. I believe cctype has a function called isprint that you can also test out. Hope that answers your question, but if not, feel free to ask.

What is new in the updated program is that I now allow the user to enter a phrase instead of hard-coding "Hello World." I also allow the user to pick the bit to be flipped rather than hard-coding 13. The program does a little parameter checking (not extensive, but a little) and does not allow manipulation of the NULL C-String terminator, only the actual characters before it.

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cassert>
#include <cstring>
using namespace std;

void SetBit(unsigned char& byte, unsigned char bitValue, unsigned char bitLoc)
{
    assert(byte <= 255);
    assert(bitValue < 2);
    assert(bitLoc < 8);

    unsigned char ormask = (1 << (7 - bitLoc));
    unsigned char andmask = 255 - ormask;
    if(bitValue)
        byte |= ormask;
    else
        byte &= andmask;
}

unsigned char GetBit(unsigned char byte, unsigned char bitLoc)
{
    assert(byte <= 255);
    assert(bitLoc < 8);

    unsigned char mask = (1 << (7 - bitLoc));
    return ((byte & mask) >> (7 - bitLoc));
}

void FlipBit(unsigned char& byte, unsigned char bitLoc)
{
    assert(byte <= 255);
    assert(bitLoc < 8);

    unsigned char bitValue = GetBit(byte, bitLoc);
    bitValue = 1 - bitValue; // change 0 to 1 or change 1 to 0
    SetBit(byte, bitValue, bitLoc);
}

int main(int argc, char* argv[])
{
    unsigned char bytes[100];
    cout << "Enter a phrase (max length 99 characters): ";
    cin.getline((char*) bytes, 100, '\n');
    int len = strlen((char*) bytes);
    if(len > 99 || !cin.good())
    {
        cout << "Phrase length is longer than 99 characters.  Exiting.\n";
        return 0;
    }
    unsigned int hBitLocation;
    unsigned int maxBitLocation = len * 8 - 1;

    cout << "Enter location of bit to flip (0 - " << maxBitLocation << ") : ";
    cin  >> hBitLocation;
    if(hBitLocation > maxBitLocation)
    {
        cout << "Bit location entered is invalid.\n";
        return 0;
    }

    unsigned int byteNumber = hBitLocation / 8;
    unsigned int bitNumber  = hBitLocation % 8;

    // original phrase
    cout << (char*) bytes << ": Bit " << hBitLocation << " is " << (int) GetBit(bytes[byteNumber], bitNumber) << "\n"; // original phrase

    // Flip bit
    FlipBit(bytes[byteNumber], bitNumber);
    cout << (char*) bytes << ": Bit " << hBitLocation << " is " << (int) GetBit(bytes[byteNumber], bitNumber) << "\n"; // misspelled

    // save wrong spelling.
    ofstream file1("file.mrm", ios::out | ios::binary);
    file1.write((char*) bytes, 12);
    file1.close();

    // Flip bit back to correct spelling
    fstream file2("file.mrm", ios::in | ios::out | ios::binary);
    file2.seekg(byteNumber, file2.beg);
    unsigned char byte = file2.peek();
    FlipBit(byte, bitNumber);
    file2.write((char*) &byte, 1);
    file2.close();

    // now open up the file again to test to make sure it's spelled right
    memset(bytes, 0, 12); // blank out memory
    ifstream file3("file.mrm", ios::in | ios::binary);
    file3.read((char*) bytes, 12);
    file3.close();
    cout << (char*) bytes << ": Bit " << hBitLocation << " is " << (int) GetBit(bytes[byteNumber], bitNumber) << "\n"; // Correct spelling
    return 0;
}

Edited by AssertNull: Fixed a few things.

0

@Null, Thanks, well the program seem not to return the correct word at the end, its return the same misspelled word. Also as of Ascii table I think I will have to dig even more to it as I can see I will be using it, but as of now its a bit confusing. Maybe there is some sort of a formular used. I can see that for "101" you used the "Dec",but as for "001" I don't seem to figure out how, I see you manctioned "97" of which I can also see on the table, but its the "001" that is confusing.

Also if I were to use now the numbers instead of alpha would I be using the "Dec"?

I will make a very short test song(MP3) which we can use as demonstration of this as well as how I could add extra data meant for translator to read first before a song is transalated back to original bytes or extraction of the added data to it.

Will post the download link. The song as just a test and it won't be a special song, will play around with some few beats and export the file to MP3 and will upload it.

0

Whoops. Try changing the 12 in lines 75 and 87and 89 to 100. See if that changes things.

As for the rest of your post, I'll have a look at it in a little over an hour.

0

OK, see new program below. I added a few printouts in different formats. I think you were getting 101 in decimal and 101 in binary mixed up. It's labeled in the program below.. Hopefully makes things more clear. Also check out C++'s bitset library. I use it in the program below and it can do more than what I used it for.

Regarding your question, whenever I write a byte in binary, I write all 8 bits. I'm also wondering whether adding the brackets and parenteses to isolate bits might have confused things rather than clarify things. I never wrote "001". I wrote "01100001". That is 97 in decimal, which is the character 'a' in ASCII. I think the confusion is that I picked the letter 'e', which is 101 in decimal. Since that number only has the digits 0 and 1 and is "01100101" in binary, and the last three binary digists are "101", I can see now how that could be confusing. So let's instead use the 5th bit and change 'H', which is 72 in decimal if you look at the ASCII chart. It is 01001000 in binary. The 5th bit is 0 (left-most is considered bit index 0, right-most bit is considered bit index 7, bit index 5 is the relevant bit and is in parentheses -- 01001(0)00. Flip that bit from 0 to 1 and you get 01001100 in binary, which is 76 in decimal, and is 'L' in ASCII. Flipping the 5th bit from 0 to 1 results in the string going from "Hello World" to "Lello World". Flip it back and you get "Hello World" again. If your confused about 01001000 in binary being equivalent to 72 in decimal, google "binary arithmetic" or "base 2 arithmetic". If ASCII is new to you, it's simply the original character encoding in the United States from way back, and it is still used a lot. Most computer programs no longer assume that everyone is using ASCII. Lots of people use some form of Unicode now.

Below is the program execution for the above example: Changing "Hello World" to "Lello World" and back by flipping the 5th bit. See the bottom of this post for the updated code.

Enter a phrase (max length 99 characters): Hello World
Enter location of bit to flip (0 - 87) : 5

Original input
Hello World: Bit 5 is 0
Byte# 0 -- Ascii: H Hex: 0x48 Decimal: 72 Binary 01001000

Bit 5 flipped
Lello World: Bit 5 is 1
Byte# 0 -- Ascii: L Hex: 0x4c Decimal: 76 Binary 01001100

Bit 5 flipped back to original, read from file
Hello World: Bit 5 is 0
Byte# 0 -- Ascii: H Hex: 0x48 Decimal: 72 Binary 01001000

Program Below

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <bitset>
#include <iomanip>
#include <cctype>
using namespace std;

void DisplayByte(unsigned char byte, unsigned int byteNumber)
{
    cout << "Byte# " << byteNumber << " -- ";
    if(isprint(byte))
    {
         cout << "Ascii: " << (char) byte;
    }
    else
    {
         cout << "Ascii: Not printable";
    }

    cout << " Hex: 0x" << setfill('0') << setw(2) << hex << (unsigned int) byte;
    cout << " Decimal: " << dec << (unsigned int) byte;
    cout << " Binary " << bitset<8>(byte).to_string() << endl;
}

void SetBit(unsigned char& byte, unsigned char bitValue, unsigned char bitLoc)
{
    assert(byte <= 255);
    assert(bitValue < 2);
    assert(bitLoc < 8);

    unsigned char ormask = (1 << (7 - bitLoc));
    unsigned char andmask = 255 - ormask;
    if(bitValue)
        byte |= ormask;
    else
        byte &= andmask;
}

unsigned char GetBit(unsigned char byte, unsigned char bitLoc)
{
    assert(byte <= 255);
    assert(bitLoc < 8);

    unsigned char mask = (1 << (7 - bitLoc));
    return ((byte & mask) >> (7 - bitLoc));
}

void FlipBit(unsigned char& byte, unsigned char bitLoc)
{
    assert(byte <= 255);
    assert(bitLoc < 8);

    unsigned char bitValue = GetBit(byte, bitLoc);
    bitValue = 1 - bitValue; // change 0 to 1 or change 1 to 0
    SetBit(byte, bitValue, bitLoc);
}

int main(int argc, char* argv[])
{
    unsigned char bytes[100];
    cout << "Enter a phrase (max length 99 characters): ";
    cin.getline((char*) bytes, 100, '\n');
    int len = strlen((char*) bytes);
    if(len > 99 || !cin.good())
    {
        cout << "Phrase length is longer than 99 characters.  Exiting.\n";
        return 0;
    }
    unsigned int hBitLocation;
    unsigned int maxBitLocation = len * 8 - 1;

    cout << "Enter location of bit to flip (0 - " << maxBitLocation << ") : ";
    cin  >> hBitLocation;
    if(hBitLocation > maxBitLocation)
    {
        cout << "Bit location entered is invalid.\n";
        return 0;
    }

    unsigned int byteNumber = hBitLocation / 8;
    unsigned int bitNumber  = hBitLocation % 8;

    // original phrase
    cout << "\nOriginal input\n";
    cout << (char*) bytes << ": Bit " << hBitLocation << " is " << (int) GetBit(bytes[byteNumber], bitNumber) << "\n"; // original phrase
    DisplayByte(bytes[byteNumber], byteNumber);

    // Flip bit
    FlipBit(bytes[byteNumber], bitNumber);
    cout << "\nBit " << hBitLocation << " flipped\n";
    cout << (char*) bytes << ": Bit " << hBitLocation << " is " << (int) GetBit(bytes[byteNumber], bitNumber) << "\n"; // misspelled
    DisplayByte(bytes[byteNumber], byteNumber);

    // save wrong spelling.
    ofstream file1("file.mrm", ios::out | ios::binary);
    file1.write((char*) bytes, 100);
    file1.close();

    // Flip bit back to correct spelling
    fstream file2("file.mrm", ios::in | ios::out | ios::binary);
    file2.seekg(byteNumber, file2.beg);
    unsigned char byte = file2.peek();
    FlipBit(byte, bitNumber);
    file2.write((char*) &byte, 1);
    file2.close();

    // now open up the file again to test to make sure it's spelled right
    memset(bytes, 0, 100); // blank out memory
    ifstream file3("file.mrm", ios::in | ios::binary);
    file3.read((char*) bytes, 100);
    file3.close();
    cout << "\nBit " << hBitLocation << " flipped back to original, read from file\n";
    cout << (char*) bytes << ": Bit " << hBitLocation << " is " << (int) GetBit(bytes[byteNumber], bitNumber) << "\n"; // Correct spelling
    DisplayByte(bytes[byteNumber], byteNumber);
    return 0;
}

Edited by AssertNull

1

I did the changes but no luck.

See above post. For future posts, I need something more detailed than "I did the changes but no luck". That doesn't tell me what the problem is. Did the program not compile? Error messages? Compile but crash? Give inaccurate results? If so, what was the problem? What input phrase did you enter? What bit number did you enter? What was the printout? What should it have been? Etcetera. Think of it as submitting a bug report. The developer wants to be able to try what you tried and see if it works.

Votes + Comments
For making your own luck.
0

Thanks will look even more into binary arithmatics, I think its need some more time to focus on it to understand it, but at least now I can see what you were talking about because by looking at the table was a bit confusing but now I know how you were getting this.

Now about the code you posted above. I added system("pause"); before the return 0; to prevent the program from closing so that I can see what it did and what it printed. well I typed a word "tweestar" and choose bit location "2" meaning I typed "2" and it changed the word from tweestar with binary 01110100 to Tweestar with binary 01010100 and it doesn't change back the 01[0]10100 or maybe its should change back the 01010100 to 01110100 of which if this is the case then its seems as if it doesn't change back the 01[1]10100 to 0. But what I'm trying to say is that its return the incorrectly spelled word back but claim it had corrected back to the original text. Please see the picture below. tta.png

1

Wow, you're right! I'm glad you attached the screenshot. Let me add "tell me which IDE/compiler/operating system you are using" for future debugging purposes. I left that off my question list. Luckily it was in the screenshot. I was using Code::Blocks and it worked. Then I tried it in Visual Studio like you and it didn't work. It was just dumb luck that it worked in Code::Blocks. See revised program below. Tested in Visual Studio. Should work now.

I added line 107 below. The file needs to be read from AND written to, so I opened the file to do both things. I correctly set the READ pointer using seekg to point to the byte to be read. That byte is read in correctly. What I failed to do is adjust the WRITE pointer using seekp to point to that byte. My guess is that in Code::Blocks, the compiler made them both to point to the same thing since I never set the write pointer, but in Visual Studio, it did not. Again, just my dumb luck that it worked in Code::Blocks. I was getting exasperated hunting down the error, thinking it was some file permissions problem, but it wasn't. It was forgetting that to set the write pointer. Anyway, program below is the same program as before, but with line 107 (the seekp line) added (I added a few comments too). Give it a try.

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <bitset>
#include <iomanip>
#include <cctype>
using namespace std;

void DisplayByte(unsigned char byte, unsigned int byteNumber)
{
    cout << "Byte# " << byteNumber << " -- ";
    if (isprint(byte))
    {
        cout << "Ascii: " << (char)byte;
    }
    else
    {
        cout << "Ascii: Not printable";
    }

    cout << " Hex: 0x" << setfill('0') << setw(2) << hex << (unsigned int)byte;
    cout << " Decimal: " << dec << (unsigned int)byte;
    cout << " Binary " << bitset<8>(byte).to_string() << endl;
}

void SetBit(unsigned char& byte, unsigned char bitValue, unsigned char bitLoc)
{
    assert(byte <= 255);
    assert(bitValue < 2);
    assert(bitLoc < 8);

    unsigned char ormask = (1 << (7 - bitLoc));
    unsigned char andmask = 255 - ormask;
    if (bitValue)
        byte |= ormask;
    else
        byte &= andmask;
}

unsigned char GetBit(unsigned char byte, unsigned char bitLoc)
{
    assert(byte <= 255);
    assert(bitLoc < 8);

    unsigned char mask = (1 << (7 - bitLoc));
    return ((byte & mask) >> (7 - bitLoc));
}

void FlipBit(unsigned char& byte, unsigned char bitLoc)
{
    assert(byte <= 255);
    assert(bitLoc < 8);

    unsigned char bitValue = GetBit(byte, bitLoc);
    bitValue = 1 - bitValue; // change 0 to 1 or change 1 to 0
    SetBit(byte, bitValue, bitLoc);
}

int main(int argc, char* argv[])
{
    unsigned char bytes[100];
    cout << "Enter a phrase (max length 99 characters): ";
    cin.getline((char*)bytes, 100, '\n');
    int len = strlen((char*)bytes);
    if (len > 99 || !cin.good())
    {
        cout << "Phrase length is longer than 99 characters.  Exiting.\n";
        return 0;
    }
    unsigned int hBitLocation;
    unsigned int maxBitLocation = len * 8 - 1;

    cout << "Enter location of bit to flip (0 - " << maxBitLocation << ") : ";
    cin >> hBitLocation;
    if (hBitLocation > maxBitLocation)
    {
        cout << "Bit location entered is invalid.\n";
        return 0;
    }

    unsigned int byteNumber = hBitLocation / 8;
    unsigned int bitNumber = hBitLocation % 8;

    // original phrase
    cout << "\nOriginal input\n";
    cout << (char*)bytes << ": Bit " << hBitLocation << " is " << (int)GetBit(bytes[byteNumber], bitNumber) << "\n"; // original phrase
    DisplayByte(bytes[byteNumber], byteNumber);

    // Flip bit
    FlipBit(bytes[byteNumber], bitNumber);
    cout << "\nBit " << hBitLocation << " flipped\n";
    cout << (char*)bytes << ": Bit " << hBitLocation << " is " << (int)GetBit(bytes[byteNumber], bitNumber) << "\n"; // misspelled
    DisplayByte(bytes[byteNumber], byteNumber);

    // save wrong spelling.
    ofstream file1("file.mrm", ios::out | ios::binary);
    file1.write((char*)bytes, 100);
    file1.close();

    // Flip bit back to correct spelling
    fstream file2("file.mrm", ios::in | ios::out | ios::binary); // open file for reading and writing
    file2.seekg(byteNumber, file2.beg);  // set READ pointer to the correct byte
    unsigned char byte = file2.peek();   // read in the byte from the file
    FlipBit(byte, bitNumber);            // change the byte
    file2.seekp(byteNumber, file2.beg);  // set WRITE pointer to the correct byte
    file2.write((char*)&byte, 1);        // write the changed byte to the file
    file2.close();

    // now open up the file again to test to make sure it's spelled right
    memset(bytes, 0, 100); // blank out memory
    ifstream file3("file.mrm", ios::in | ios::binary);
    file3.read((char*)bytes, 100);
    file3.close();
    cout << "\nBit " << hBitLocation << " flipped back to original, read from file\n";
    cout << (char*)bytes << ": Bit " << hBitLocation << " is " << (int)GetBit(bytes[byteNumber], bitNumber) << "\n"; // Correct spelling
    DisplayByte(bytes[byteNumber], byteNumber);
    return 0;
}

Edited by AssertNull

Votes + Comments
Its does the job now.
0

You are the pro... Thank you so much. Now I think I will have to finilize and wrap everything up here, but I would like to ensure that I'm on the right path. BitLocation is a BitPosition right? to test this out with an mp3 file I will have to change from getting the string from a user by typing a phrase but to read a mp3 file and get the total bytes (bits) which I can say which to be altered, am I correct? Now lets say I did modify "D", when I read on the MP3 Tech web site, they said

By re-calculating the CRC and comparing its value to the sored one, you can check if the frame has been altered during transmission of the bitstream.

Which I think will be a problem because it will just recalculate and see that it has been altered and corrects it, what could be the solution to this dispite just doing the modifications and changing the extention? Here is the website

Thank you again, this has teached me quite a lot of things and even though some things were sounding way complicated, but with your guidance there was a light. Thanks to each and everyone of you and @Null you the best. I wasn't going to figure any of that out.

Edited by Mr.M: Adding a reference website

1

https://en.wikipedia.org/wiki/Cyclic_redundancy_check

CRC's are generally used to verify the integrity of a file against data transmission errors and other types of unintentional tampering. The method/algorithm used is intentionally transparent, simple, and public, so unlike Hash functions and encryption to guard against intentional tampering and cracking, which are intentionally often made to be as difficult for unauthorized use as possible, CRC's won't help you much against a dedicated human opponent who realizes that you are intentionally calculating them wrong.

In your case, however, they do a few things for you. One, most of the MP3 players out there trying to play your file will assume that the CRC is used in the normal way (i.e. not used to confuse them), so they will calculate the CRC, notice that it does not match what is in the file, and assume that segment of the file is corrupted and skip it. Since all or the vast majority of your CRC calculations will be intentionally wrong, IF the mp3 player follows the mp3 format, your file will be unplayable.

If the mp3 play DOES NOT calculate and not play the bad CRC segments, if you do nothing but mess around with the 16 CRC bits and the D bit in each segment and do not change the actual sound data, the song will play. However, all is not lost. You can use those 16 bits per segment to store either encoding information or part of an encryption key. Keep in mind that every segment will can have a CRC, so you have 16 bits PER SEGMENT that you can store information on, so that's thousands or even millions of bits to play around with. To put things into perspective, you only need 256 bits to store the key for the most secure form of AES encryption.

How you encode and/or encrypt the data is up to you, I was just pointing out that, as opposed to just using the single H bit, using the D bit and the 16 free CRC bits per segment that come with that D bit makes your job easier, plus there's the added benefit that simply setting that D bit and doing ANYTHING with those CRC bits, even just making them completely random, and not changing anything else will be enough to prevent many mp3 players from playing the song, whereas just manipulating the H bit won't.

So, to sum up, IF you ONLY changed around the D bit and the associated CRC bits and IF I KNEW that was all you did, I could easily write the same program you will to calculate the correct CRCs or unset the D bit and take those CRC bits out and the song would be completely playable, so I'm thinking you need to do something more. An example might be this. Let's pretend that the "song" part is 11 bytes instead of 627. Let's say it storres "HELLO WORLD" again. Here's the original header plus data (for the original, I set D bit to 0 below-- ie no CRC). Note - dashes are just to make the viewing easier

AAAAAAAA   AAABBCC0   EEEEFFGH   IIJJKLMM ---- HELLO WORLD

Replace D with 1 and add 16 bits / 2 bytes of CRC -- make those bytes 24 and 32 (explanation to follow)

AAAAAAAA   AAABBCC1   EEEEFFGH   IIJJKLMM ---- 24 32 ---- HELLO WORLD

For our encoding, the 32 means add 32 to to each byte (again, "HELLO WORLD" in ASCII. Add 32 to each byte makes "hello world")

AAAAAAAA   AAABBCC1   EEEEFFGH   IIJJKLMM ---- 24 32 ---- hello world

The 24 represents an offset. The last 24 bits are put in front, all other bits are shoved back 24 bits/3 bytes back.

AAAAAAAA   AAABBCC1   EEEEFFGH   IIJJKLMM ---- 24 32 ---- rldhello wo

That's just a very very simple encoding. If you know the method, you can easily reverse it, but if you are able to keep the method secret, it scrambles everything up. You'll likely want something much more complicated, but that's the idea. Something easy to reverse if you know the format, but difficult if you do not.

Edited by AssertNull

0

The 100 I have to change it right? because even if I try to read a file it will write the file with 100 bytes, but the original file is 1.22MB and when I read it, it "4294967295" but I don't seem to get it how to read and write it, If I change the "bytes[100]" to match up with the file, like this "bytes[4294967295]" I get an exceeption that its can't exceed some "0x....." something.

This is how I attempted to read the file:

unsigned char bytes[100];
ifstream infile;
infile.open("c:\users\me\desktop\MrMSimplemp3.mp3");
infile >> bytes;
// I commented out the cin.getline((char*)bytes,100, '\n'); because I already read the file.
int len = strlen((char*)bytes);
if (len > 99 || !cin.good())
{
cout << "Phrase length is longer than 99 characters. Exiting.\n";
return 0;
}
unsigned int hBitLocation;
unsigned int maxBitLocation = len * 8 - 1;
cout << "Enter location of bit to flip (0 - " << maxBitLocation << ") : "; // This is where I get that big number thats start with 42.

The rest of the code is the same didn't change anything.

Edited by Mr.M

0

@Jim can you provide more details to this bytes(4) = Asc("\") I also tried this and I didn't write the part to write the bytes back to file because at this point I didn't understand how to locate a bit based on that code. So what I did was that I tried to display it back but lots of confusion came up. I added a label to my form and when I point it to display the bytes.ToString its just display System.Byte[] which I assume its some sort of array where I will have to point to which array to display. Then I did this Label1.Text = bytes(numberhere) and if I change around the number I get diffent output numbers in some numbers I get 0. Now if I change it looking to the MP3 Tech website to test with bits position I don't seem to get the results as its is said to that website.

0

4,294,967,295 is about 4 gigabytes. No wonder you got an error. Even if you made that number 1,500,000 or whatever 1.22 MB is, I wouldn't count on being able to get that much memory on the stack (as opposed to dynamic memory, which comes from the heap). Even on the heap, you might have a hard time getting enough CONTIGUOUS memory for that large of an array.

My program was just a sample program to show you the idea. You'll need to tailor your program to the mp3 format you linked in the beginning of the thread. There's nothing special about the number 100 as the buffer size. I just picked it because it was more than big enough to handle my little sample cases. For your project, you'll likely need a bigger buffer. Earlier in the thread, people were asking you what you were doing and you couldn't really share the details of the why and how, but you said it didn't matter since you had those parts under control, so I just wrote a program that showed a method of changing bits in a file.

There are a lot of ways to do this project. You may or may not decide to read the entire file into a single buffer like I did. With large files, you likely will not be able to simply be able to change that 100 to a larger number because at some point, you'll run out of memory. Where that point is will vary, but you clearly exceeded it with the huge number you tried.

You'll most likely need to use dynamic memory. Google "C++ dynamic memory vs static memory". Long story short, you have more memory available to you on the "heap" than on the "stack". My program uses the stack since 100 is a small number and that's not an issue. If you are using C++, you'll probably use the "new" command to get access to the heap memory and you might need to read it in segments, which is easy to do since it's already in segments of less than 1000 bytes each from what it looked like in that website explainer that you linked. I would set up a class or a struct (same thing really) that matches the mp3 segments. You'll likely have a vector or a linked list of structures. C++ provides those containers for you.

I don't know your C++ skill level or the algorithm you've decided on, so can't really offer much other than you'll likely be unable to change that buffer size from 100 in my program to a number large enough to store an entire mp3 song in one contiguous array.

0

Thanks well I'm pretty new to C++, and I'm still learning it along the way as this entire system most of its parts require the use of C++, thats also include other parts which are not MP3 related, so yea I'm new to C++. In VB.NET there is a way to read a file but not read the entire file, lets say I were to read a text file, in VB.NET you can read one line/many lines, entire file. I'm sure even C++ has some capabilities to do so, but not sure in reading as bytes, but I think its no difference except the data type it self read.

As of the algorithm well after you also mentioned "D", "M", I then had another Idea, but for now what I'm dealing with is now the understanding of all of this and be able to test it on actual bits. Also your last samples where you used the frames, that what I meant as you have changed the "D" from "0" to "1", and stored some extra information to the file.

I've added the test song that I made, the song is 1.22MB and the length is 00:01:04, the format is mp3. Download it here valid for 7 days only

0

Well I can play the song as an mp3 on VLC Player and hear the . Not sure if I was supposed to be able to do so. As far as C++ versus other languages go, if you are more experienced in other languages, they generally all have the ability to manipulate files and isolate/change/read bits and bytes, so don't learn C++ just to do this. I imagine there are tons of libraries out there that help you manipulate mp3 files in all sorts of languages, though I'm not familiar with them.

But if I was doing what you are doing, I imagine I wouldn't even bother learning the mp3 format. I would simply work with the raw file bytes and encrypt/encode and decrypt/decode and stick whatever I had to in front of the actal mp3 file bytes to help me do that, if needed. In other words, when encoding/encrypting, I wouldn't care the mp3 data, I would treat it like a big blob of data and would not care whether I was changing the H Bit or the D bit or the CRC bits or whatever and the end result would be a file that looked nothing like an mp3 file and would be completely unplayable by an mp3 player, and I wouldn't give it a .mp3 extension. Then I'd decrypt/decode the file and turn it back into an mp3 file with a .mp3 extension. From your description, it seems like this would be the way to go, but as you said, you are not able to share other details, which is fine, just make sure that it in fact WON'T work for you. Don't make it complicated if it doesn't have to be.

Good luck.

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.