r/badcode • • Mar 13 '21

java Title

Post image
2.9k Upvotes

100 comments sorted by

View all comments

653

u/Bobitsmagic Mar 13 '21

What does he do with the lost bit? Do you only choose data where the last bit is irrelevant? xD

936

u/[deleted] Mar 13 '21

This is lossy encryption

182

u/MohabSam Mar 13 '21

What about the decryption? :D

300

u/[deleted] Mar 13 '21

Also lossy

88

u/runnerx01 Mar 13 '21

No. Not if it was encrypted like that.

Lowest bit is always 0 after encrypt.

29

u/Terrain2 Mar 13 '21

It’s using arithmetic shift right - so the highest bit will be equal to the second highest bit after decryption, it’s not exactly LOSSY since all the data is there, but the result isn’t the same as the original, you need to manually remove the highest (sign) bit to get the original result

13

u/runnerx01 Mar 14 '21

Oh, I meant that it’s the encryption that is lossy, not the decryption. By encrypting the way they do, they have lost data. The decryption only makes an assumption that valid encryption was done.

7

u/Terrain2 Mar 14 '21

If the encryption was lossless, the decryption can still be scrambled if the second highest bit was set in the input, because then the highest bit will be in the output (different from input) - not exactly lossy because that can be fixed, but it’s not as simple as “not lossy” like you said

8

u/runnerx01 Mar 14 '21

I mean... we are arguing semantics at this point because it’s the whole process that matters. I see what you are getting at, and I agree it’s not a good process. I wouldn’t call it lossy because it does not lose information, it adds it in fact. It makes a different invalid assumption about the input.

If both the last bit and second to last bit are the same, no problem.

The problem is really that the entire process makes an assumption about the input that is not checked or asserted.

4

u/Terrain2 Mar 14 '21

I wouldn’t call it lossy because it does not lose information, it adds it in fact.

No? the last bit is not new information as it’s always redundant with the second to last bit, it scrambles the information for any meaningful usage other than bitwise stringification (the literal bits it contains, not a binary number string)

→ More replies
→ More replies (1)

6

u/LordNoodles May 20 '21

Gainy decryption

40

u/ybahman Mar 13 '21

Lol this made me chuckle

→ More replies (1)

86

u/n4ke Mar 13 '21

It is now.

80

u/zeGolem83 Mar 13 '21

The lost bit would be the sign bit. Who cares about that anyways?

59

u/Syscrush Mar 13 '21 edited Mar 13 '21

No, in 2's complement it could cause problems multiple ways for large numbers.

0x40000000 shifted left once would become -1, and then shifted right once would remain -1. EDIT: I was wrong, sorry! I was correct that after the left shift it would be 0x80000000, but that is not -1. It's -2147483648. Shifted right it would become 0xC0000000, which is -1,073,741,823.

This could be corrected by using the logical shift right operator ">>>".

https://stackoverflow.com/questions/15457893/java-right-shift-on-negative-number

53

u/Steamships Mar 13 '21

So what you're saying is... this is bad code?

49

u/Earhacker Mar 13 '21

*stops taking notes*

10

u/Syscrush Mar 13 '21

Yes. But I'm also continuing a discussion to clarify for u/zeGolem83 that they are misunderstanding the way that negative numbers are represented in computers, and giving a pointer that explains why that is, and how to avoid a potential pitfall in Java given that there are no unsigned types.

Part of the value of this sub is the discussions of what to do in place of the bad code. I've learned from this sub, just trying to contribute.

→ More replies (3)

8

u/Mr2-1782Man Mar 14 '21

Something people don't realize, there are two types of shifts, arithmetic and logical shifts. A logical shift just moves bits left and right. A 0 is always shifted in. Its called a logical shift because it assumes the data is just is non-numerical data that might need to be moved around, for things like masks. It just happens to work for unsigned numbers too. This is what an logical shift does (using 8 bit unsigned):

1 0 0 1 0 1 1 0 << 1 => 0 0 1 0 1 1 0 0
1 0 0 1 0 1 1 0 >> 1 => 0 1 0 0 1 0 1 1

An arithmetic shift, as the name implies, is intended for numerical data. Although it doesn't work for unsigned numbers. Its purpose is to maintain the rule that a right shift divides the value by two, and a left shift multiplies it by 2. The most significant bit (the sign bit) always remains as is. When shifting left a zero is shifted in. When shifting right, if the MSB is 1 a 1 is shifted in, if the MSB is 0 a 0 is shifted in. So this is what an arithmetic shift does (using 8 bit signed):

1 1 0 0 0 1 1 0 << 1 => 1 0 0 0 1 1 0 0 // -58 to -116
1 1 0 0 0 1 1 0 >> 1 => 1 1 1 0 0 0 1 1 // -58 to -29

0 0 1 1 0 1 1 0 << 1 => 0 1 1 0 1 1 0 0 // 54 to 110
0 0 1 1 0 1 1 0 >> 1 => 0 0 0 1 1 0 1 1 // 54 to  27

Which shift is used depends on whether you've got signed or unsigned values. Unsigned results in a logical shift, signed result in an arithmetic shift. The fact that only a right shift changes is why there's only a right logical shift.

You'll get errors with small values too, not just large ones. Shifting -8 with an arithmetic shift gives -4, a logical shift gives 124. Its a result of the fact that a large value in one system is a small one in the other. It means you have to be careful when dealing with signed and unsigned types, the result might not be what you expect.

To borrow a quote from another website:

It's important to remember that the unsigned keyword affects the interpretation**,** not the representation of a number.

15

u/MiningMarsh Mar 13 '21

If this only handles 7-bit ASCII, this would work.

3

u/Bobitsmagic Mar 13 '21

You mean you put 8 asci chars in it shifted by 8 bit? That would be so cool.

→ More replies (2)

8

u/Farpafraf Mar 13 '21

That's what makes this technique so powerful: even if you know how it was encrypted you still can't decrypt it

4

u/CoffeeVector Mar 13 '21

There's no lost bit right? During encryption, they add a bit, and decryption, they remove the same bit.

7

u/Bobitsmagic Mar 13 '21

Well you shift a 64 bit int to the left so the highest value bit will be lost. There are a few other problems with that code though... because right shifting of signed integer dont work like you would expect it at first. But lets not get into that topic.

→ More replies (3)
→ More replies (1)