Discuss Scratch

ShieldOS
Scratcher
30 posts

Binary Encoder

Currently I am trying to make a way on Scratch of converting Text to ASCII to binary. I have done the first part but I am having trouble on the second bit and I was wondering if anyone had suggestions on how I could do this? Thanks! ~ Shield
Arcanum
Scratcher
57 posts

Binary Encoder

Have you got an example of what you mean when you say you have got the first part done? Have you got a character or a number?
Zro716
Scratcher
1000+ posts

Binary Encoder

use my base converter. It's simple and works for binary up to base 32.
ShieldOS
Scratcher
30 posts

Binary Encoder

Arcanum wrote:

Have you got an example of what you mean when you say you have got the first part done? Have you got a character or a number?
I have done the bit where it converts the text into digits. The part I need help with is converting the digits into binary.

Zro716 wrote:

use my base converter. It's simple and works for binary up to base 32.
Thanks but I need base 64 so I'll try and look at your code and see if I can make it with credit.
Zro716
Scratcher
1000+ posts

Binary Encoder

ShieldOS wrote:

Zro716 wrote:

use my base converter. It's simple and works for binary up to base 32.
Thanks but I need base 64 so I'll try and look at your code and see if I can make it with credit.
Base 64 sounds like you need more than the English alphabet to substitute for numbers 10-63. I think you mean 64-bit…
Arcanum
Scratcher
57 posts

Binary Encoder

ShieldOS wrote:

Arcanum wrote:

Have you got an example of what you mean when you say you have got the first part done? Have you got a character or a number?
I have done the bit where it converts the text into digits. The part I need help with is converting the digits into binary.
So you've got something that will convert from a string like “FRED” to a list of integers (71,83,70,69); and now you want to convert those integers into a binary stream so that you can do base64 encoding on it?

So you want to go from (71,83,70,69) to binary (01000111, 01010011, 01000110, 01000101) to resplit into groups of 6 bits with zeros padding the last group (010001, 110101, 001101, 000110, 010001, 010000) back to decimal (17, 53, 13, 6, 17, 16) convert to b64 “R1NGRQ” and pad to a multiple of 4 characters “R1NGRQ==”.

“FRED” actually doubles in size!

I'm sure I can knock something together to help demonstrate the stages needed if you want any help.
n00b_guy
Scratcher
28 posts

Binary Encoder

Let's break it up into parts.
Part 1 - Finding the number of digits:
Your program will have to calculate how many digits the binary will be. To do this you have to first get a power of 2 that is just higher than the original number. Next, you have to make it 1 digit shorter, since the power of 2 is greater than your number, so it will return 0 for your first digit.

Part 2-Converting
For this part you will need for variables. The original number, a temporary number, a power of 2 and a variable to use to change values by 10000, 1000, 1 etc.
If the temporary number is greater than the next power of 2, add 1000000 or 100 depending. Repeat until power of 2 is less than 1. This block may be helpful:
10^of9

Hoped I helped.
ShieldOS
Scratcher
30 posts

Binary Encoder

Arcanum wrote:

ShieldOS wrote:

Arcanum wrote:

Have you got an example of what you mean when you say you have got the first part done? Have you got a character or a number?
I have done the bit where it converts the text into digits. The part I need help with is converting the digits into binary.
So you've got something that will convert from a string like “FRED” to a list of integers (71,83,70,69); and now you want to convert those integers into a binary stream so that you can do base64 encoding on it?

So you want to go from (71,83,70,69) to binary (01000111, 01010011, 01000110, 01000101)
That is what I mean. All the stuff you said after this I did not under stand.

n00b_guy wrote:

Let's break it up into parts.
Part 1 - Finding the number of digits:
Your program will have to calculate how many digits the binary will be. To do this you have to first get a power of 2 that is just higher than the original number. Next, you have to make it 1 digit shorter, since the power of 2 is greater than your number, so it will return 0 for your first digit.

Part 2-Converting
For this part you will need for variables. The original number, a temporary number, a power of 2 and a variable to use to change values by 10000, 1000, 1 etc.
If the temporary number is greater than the next power of 2, add 1000000 or 100 depending. Repeat until power of 2 is less than 1. This block may be helpful:
10^of9

Hoped I helped.
Sorry I don't understand what you mean by pretty much all of this. Sorry.
Arcanum
Scratcher
57 posts

Binary Encoder

Okay, the first step, going from numbers to a string of binary digit. This is a quick hack, but it'll do the trick.
defineConvertnumberASCII_ValintoabinarystringstoredinvariableTmp_BinarysetTmp_CharValtoASCII_Val Have to copy this to a temporary variable because we need to change itsetTmp Binaryto Blank to start off withsetBitPositionto128 128 is 2^7 - the top bit of an 8 bit integer setrepeat8ifTmp_CharValue<BitPositionthen Process 8 bits If Tmp_CharValue is less then BitPosition, then that bit must be clear and we add a 0 to the binary stringsetTmp_BinarytojoinTmp_Binary0else If Tmp_CharValue is greater or equal to BitPosition, then that bit must be set and we add a 1 to the binary stringsetTmp_BinarytojoinTmp_Binary1setTmp_CharValuetoTmp_CharValue-BitPosition Subtract that bit from Tmp_CharValueendsetBitPositiontoBitPosition/2 Dividing by 2 works down through the bits 128, 64, 32, 16, 8, 4, 2, 1end

When this custom block returns Tmp_Binary will hold the binary representation of whatever number you passed in as an argument to ASCII_Val.

The routine uses two additional variables: Tmp_CharVal and BitPosition. Both of these are undefined upon exit (that means you shouldn't expect any particular value to be held in them).

Hope that helps you along the next step.

Last edited by Arcanum (Sept. 10, 2014 23:00:09)

Arcanum
Scratcher
57 posts

Binary Encoder

PS: Have you found a way to overcome the case insensitivity of Scratch comparisons? I've tried doing a base4 encoder, but case insensitivity is really getting in the way at the moment - I've been trying to think of a different way of doing it but not come up with a way yet.

Case insensitivity, in case you don't know what I mean is what you get when you do an if comparison between strings and it ignores the difference between upper and lower case - so ‘A’ equals ‘a’, ‘B’ equals ‘b’ and so on… to properly encode I need to be able to pick out ‘A’ and ‘a’ as different characters.

If you've fathomed a solution to this, then you can help me too.
ShieldOS
Scratcher
30 posts

Binary Encoder

Well I did not understand the method but I shall try it! As for your problem on scratch I normally differentiate “A” from “a” by adding another symbol (a symbol you wouldn't normally see on a keyboard) to the end of lower case letters and then telling the script that if it has the other symbol then it is lowercase. Hope that helped! Sorry if I misunderstood what you said
ShieldOS
Scratcher
30 posts

Binary Encoder

So I tried your method and I typed “Hello”. This is what I should have got “0100100001100101011011000110110001101111” but what I actually got was this “110100100010000100000100000010000000”. The first one is 40 digits long, as it should be, but the second is 36 which is kind of confusing. I will try and debug it but I may find it hard as I don't understand how what you typed works. :3 The chances are that it is a piece of my coding clashing with a piece of yours. Thanks for all the support anyway!
Arcanum
Scratcher
57 posts

Binary Encoder

I've attempted to work out how you have ended up with ‘110100100010000100000100000010000000’; with 36 bits, something is going astray: that isn't a round multiple of 8 bits.

May I suggest that you add the generated Tmp_Binary into a list that you can display as a list rather than adding all to a single string for now?

Now, I'll see if I can explain what the routine I expressed above does. I tried to include some comments to help out, but I'll be more explicit.

First off this is a custom block - a quick glance through your shared projects has me wondering if you've used these, but unless you tell me otherwise I hope I'll be fairly safe in assuming that you know what they are.

It is designed to accept a single parameter, a number, and within the custom block that parameter is referred to as ASCII_Val

So, to start off, there is a header to describe the block and a few variable initialisations, a couple of temporary variables (ideally created as ‘sprite only’) and a result variable:
  • Tmp_CharVal - Temporary variable used to hold the passed value at first and then have each bit removed as it goes along.
  • BitPosition - Temporary variable used to check whether a bit is set or not. See description below about this.
  • Tmp_Binary - The variable which will have the string of zeros and ones returned in. I named it Tmp_Binary to emphasis that it cannot be used to keep the value more than temporarily, the next time you call the block will cause the next result to replace the first.
defineConvertnumberASCII_ValintoabinarystringstoredinvariableTmp_BinarysetTmp_CharValtoASCII_Val Have to copy this to a temporary variable because we need to change itsetTmp Binaryto Blank to start off withsetBitPositionto128 128 is 2^7 - the top bit of an 8 bit integer set

Now, a little more detail about BitPosition.

If I'm lucky, there'll be a graphic here showing eight bit positions, numbers seven to zero above the bit pattern for the letter ‘H’.

Bit 7 in this example is zero, however, if only bit 7 was set to one and everything else was set to zero, then the value would be 128, that is 2 x 2 x 2 x 2 x 2 x 2 x 2, or 2 to the power of 7.

So, if we compare the value with 128 and it proves to be less than 128, we know that bit 7 is off and we insert a ‘0’ into the result string; otherwise it must be set and we insert a ‘1’ into the result string.
Bit 6 on its own would have the value 64, this is 2 x 2 x 2 x 2 x 2 x 2, or 2 to the power of 6. Clearly the easy way to get the variable BitPosition from the value 128 to the value 64 is by dividing it by 2. However, if bit 7 was set, we can't just compare with 64 because bit 7 would incorrectly give a false indication of bit 6 being set. So going back a step - if we found that bit 7 was set, we should subtract it away from the value we're testing in order that bit 6 becomes exposed.

This loop goes through that process eight times - once for each bit:
repeat8 Process each of the 8 bits in the ASCII Value Compare the character value with the value of the bit positionifTmp_CharValue<BitPositionthen If Tmp_CharValue is less then BitPosition, then that bit must be clear and we add a 0 to the binary stringsetTmp_BinarytojoinTmp_Binary0else If Tmp_CharValue is greater or equal to BitPosition, then that bit must be set and we add a 1 to the binary stringsetTmp_BinarytojoinTmp_Binary1 Subtract that bit value from Tmp_CharValuesetTmp_CharValuetoTmp_CharValue-BitPositionend Dividing by 2 works down through the bits 128, 64, 32, 16, 8, 4, 2, 1setBitPositiontoBitPosition/2end

For the ‘H’, with an ASCII value of 72, it will go through the following process:


Again, I hope that that the image shows up… I've had to create an account at imageshack just to upload them since it won't take links from my own server.

Finally, I've pruned out a load of stuff from my test program so that you can see how it works in operation - my test routine that goes up to this point can be found at http://scratch.mit.edu/projects/26604995/

Hope that helps.

Powered by DjangoBB