|
There are no philosophers in Florida. The alligators ate most of them, and the rest realized that FL is not the place to live if you are practicing philosophy.
|
|
|
|
|
You receive a Doctorate of Philosophy when presenting new work proving that you can extend science. It is not considered science though when you submit it. It becomes science when it is peer-reviewed and has gone through the other procedures that get it accepted into what is considered the body of science. Until then, your work is considered philosophy.
|
|
|
|
|
Just remember when dealing with thesis papers:
BS => Bull S.
MS => More of the Same
PhD => Piled Higher and Deeper
|
|
|
|
|
On a serious note, I admire people who can own their gaffs proudly. Much respect.
cheers
Chris Maunder
|
|
|
|
|
A little late to disguise myself and slink away at this point anyway. You people recognize me.
Real programmers use butterflies
|
|
|
|
|
|
I'm reverse-engineering some code, and I've found this as the "decryption" for some data:
unsigned char encrypted[...];
unsigned char decrypted[sizeof(encrypted)];
for (int i = 0; i < (int)sizeof(encrypted); i += 4)
{
DWORD temporary = ((((DWORD)encrypted[i + 0]) << 24) & 0xFF000000) |
((((DWORD)encrypted[i + 1]) << 16) & 0x00FF0000) |
((((DWORD)encrypted[i + 2]) << 8) & 0x0000FF00) |
((((DWORD)encrypted[i + 3]) << 0) & 0x000000FF);
temporary = temporary * 487709855;
decrypted[i + 0] = (BYTE)((temporary & 0xFF000000) >> 24);
decrypted[i + 1] = (BYTE)((temporary & 0x00FF0000) >> 16);
decrypted[i + 2] = (BYTE)((temporary & 0x0000FF00) >> 8);
decrypted[i + 3] = (BYTE)((temporary & 0x000000FF) >> 0);
} I remember seeing this sort of thing before, but I don't remember what it's called. Any suggestions?
Software Zen: delete this;
|
|
|
|
|
Obscurity?
Edit, how about:
Affine cipher - Wikipedia[^]
Further edit:
If it is Affine, is it Quadruple-Affine? Effectively using a different key for each of four bytes all at once?
modified 24-Nov-21 16:59pm.
|
|
|
|
|
I don't know its name, but I recognise the algorithm.
It's big-endian 32bit, with the encryption and decryption keys being multiplicative inverses mod 2^32.
On a big-endian machine, the loop becomes something like
for (int_32 i = 0; i < sizeof(array); i++)
{
array[i] *= magic;
} where (encrypt_magic * decrypt_magic) % (1<<32) == 1
As an encryption algorithm, it's nuisance value only. But I have used it a few times just to discourage tampering.
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
Thanks for the information. I recognized the form, but couldn't remember the rationale. The mental attic has become quite cluttered.Peter_in_2780 wrote: As an encryption algorithm, it's nuisance value only I recognized that. Even the Tiny Encryption Algorithm (TEA)[^], which I've used a number of times, is a lot more complicated.Peter_in_2780 wrote: I have used it a few times just to discourage tampering That is definitely the purpose here.
Software Zen: delete this;
|
|
|
|
|
Sometimes you get asked to implement an encryption in ten minutes without (or with very limited) internet access for stuff that can stay clear-text anyway.
These are the results.
GCS d--(d-) s-/++ a C++++ U+++ P- L+@ E-- W++ N+ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t+ 5? X R+++ tv-- b+(+++) DI+++ D++ G e++ h--- r+++ y+++* Weapons extension: ma- k++ F+2 X
|
|
|
|
|
Base-64.
|
|
|
|
|
Keeps away a lot of amateurs. XOR your base64 to be safe from them hobbyist hackers.
Bastard Programmer from Hell
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
That's a very bad "algorithm". In fact the transform is not even bijective, because the "magic number" used for the multiplication is not a prime number (it is evidently a multiple of 5, even if it has no divisor by 2, which is a very weak but insufficient condition). This code creates some collisions.
Basically, this should just be a weak "hashing function" for use to compute fast hash keys in hash tables, to distribute the hash keys in a pseudo-random order, however it is limited to hashing short strings (hash tables require a small number of bits in the hash value, but here this hash has the same size as the input, which is assumed to be a multiple of 4 bytes, so typically an hash table would only distriobute the first few bytes of the input strings, ignoring completely the end).
It is extremely easy to decrypt by a very basic cryptanalysis (simply based on statistics, because each block of 4 bytes is encrypted separately, independantly of their position in the data stream).
If there's any app using this code, it should be marked as severely attackable (much more than MD5 which is already easily attackable, even when given some salt).
A much better affine transform would use the result of the previous block as an additive salt for the next block of 4 bytes, and the first block should be salted by an initial 32-bit constant. If this is used to compute a hash key, the hash should be the value you get from processing the last block, i.e. the last 4 bytes, and never the first 4 ones.
Beside this, the bitshifting done here is just here to allow processing unaligned block, in a very inefficient way: you don't need masking the "temporary" with 0xFF000000... if you just cast the temporary value to a byte, and the first part is extending a byte to a 32-bit DWORD before left-shifting, meaning that masking the low bits is unnecessary, and making the high bits would be also unnecessary of the left-shifting was not arithmetic but logical using unsigned byte: DWORD is the incorrect type to use because it is signed. May be the compiler will optimize this, but this code is just waste
But you should be aware that this code processes bytes past the end of the data, if the datasize (sizeof encrypted = sizeof decrypted) is not a multiple of 4 bytes: up to 3 trailing bytes have unpredictable contents and trying to access them could cause memory access violation: this is a clear case of BUFFER OVERFLOW.
|
|
|
|
|
The multiplier doesn't need to be a prime, it needs to be co-prime to 232. So it just needs to be odd, and it is. The inverse of 487709855 is 2188132191 (proof: 487709855 * 2188132191 = 1). It's a very weak encryption, but it's not incorrect.
|
|
|
|
|
|
IDK. I don't really want to call it an affine cipher, it kind of is, but that name is mostly used when the letters are independent, which here they are not (the upper byte of a block has four letters mixed together, the lowest byte in a block is the same as in a normal affine cipher though). Maybe it can be called an "affine block cipher", and there are some references to such a thing, but too few to really make sense. Also, the addition missing (or adding zero I suppose) is possibly important enough to warrant a different name, because it enables a fun "sum of ciphertexts decodes to the sum of corresponding plaintexts" attack, without needing any knowledge of the keys. It's not MMB, which is really close, but that uses a different modulus (for less asymmetric mixing).
|
|
|
|
|
yes its call copy a 8 bits in to 32 bit type, i do not believe that magic number qualifies it as encryption either. and why is this so efficient it s f***ing the whole thing is dome in one operation its seems dosn't matter how complex it seems its the same as almost the same as 1 + 1
|
|
|
|
|
Just consider if your table size is a multiple of 5...
The hash value itself, even if it's a power of 2, is not sufficient: the multiplier msut be a coprime of the integer size (a power of 2, so the multiplier must not be even) cannot AND of ANY hash table size (which can be quite arbitrary integer, not necessarily a power of 2).
That's why using primes is always better. And why usually, the factor used in Fast Knuth Algorithm is a prime near the value of sqrt(2^(N-1)), for a generated hash value in [0, 2^N), i.e. the largest prime near below 2^(N/2); for a 32-bit hash value this means using the prime factor just below 65536, like 65521 or 65537 (but the 1st is better as the number of bits 1 or 0 are more equally balanced); but if your hash value will index strings of 1-byte characters or variable-length array of bytes (which are 4 times smaller in bitsize than the hash value), you'll use a factor near 2^4, rounded up to take into account for short strings, so you'll use the factor 17 (which contains 2 bits set to 1 and 2 bits set to 0: it is balanced and has good randomization properties): using a factor of 17 is also very fast to compute even if you don't have hardware multiplier in the instruction set of your ALU, or even if you don't have hardware shifts (it can be computed noly with 5 additions in that case, and a single pair of CPU registers; but this use is now extremely rare except in very cheap 8-bit controlers).
|
|
|
|
|
That's a strange argument given that this was about encryption, not a hash. It's supposed to be an invertible operation, that's all. There is no table.
|
|
|
|
|
A hash may be invertible if it contains at least as many bits as the input (though it is not is major usage where this is geenrally the reverse).
But the arguments are the same: you just want a perfectly flattened distribution of bits in the result, and for using it as an encryption, you must ensure that there will NEVER be any collision (so the distribution is almost perfectly flattened with collision lists for each hash value being either 1 or 0, a property that a good hash algorithm should have as well when their input has the same (or smaller) bitsize as their output. But actually a good hash will want to have this flattened distribution even if you truncate the hash value to less bits (the same will be true if you use it as an invertible encryption that must be secure, i.e. where you cannot guess the decryption key if you konw some pairs of clear-text input and resulting "hash" value, which should still be invertible but only when you know the decryption key or when you can generate it easily because you know the encryption key).
Many encryption algorothms also depend a the existence of a "securely strong" hash key (at least to generate the encryption/decryption keys), and the inversible operation of encrypting/decrypting may as well be used as a hashing function (once you give it one of the keys).
Note that encrypting very short messages even with a very strong encryption algorithm with long keys causes a major problem because the result is no longer a flat distribution; that's why strong encryptions require padding those messages with enough bits so that they become longer than the minimum length required for the keys. Such padding are not random, but they cannot be static (e.g. all zeroes), but should be generated by a strong hash: very short messages will then become undistibuishable from long messages that have the desired flattened distribution of bits in their encrypted patterns.
|
|
|
|
|
hash values are not random
|
|
|
|
|
I did not say they are "random", jsut that they are "sufficiently randomized" (meaning that it generates a sufficiently "flattened" distribution in the hash space to minimize the number of collisions of keys and the average access time in the hash table). Generally keys used in hash tables are not flattened, and that's where you need a good hashing function that *pseudo*-randomizes the distribution of their bits.
I've seen videos using STUPID hash functions like:
int hash(char*s) {
hash=0;
for (i=0, s[i] != '\0', i++) hash = hash*(i+1) + s[i];
return hash%N;
}
Here of course this is stupid as not all characters in the string have the same weight, some of them are even completely ignored in the result.
If you don't know what is a hash function and what it must respect, your hash table will not optimize anything and in fact lookups in such hash table will be even SLOWER than a full table-scan where you add keys at end of an array.
If you don't know which factor to use for computing hash value, just use 17, and use an hash table size which is a power of 2 (at 2^4, but an hash table size of 32, 64, 128 or 256 is better); if your hash table size is larger, adjust the factor so that it is rougly doubled (keeping it as a prime) when the hash table size is quadrupled (and take into account the bitsize of each individually "fragment" of the hash key that you "feed": most apps will feed basic integers or bytes). And for evaluating the table size needed, consider the number of keys you'll store, and IF collisions will be managed by storing keys in a separate linked link list, or in "successor" free slots inside the table itself (which increase the "fill factor" and the likelyhood of collisions with other hashes): your hash table should be about 33% to 67% filled with keys to avoid wasting space while keeping collisions still infrequent, with average length of collision lists per bucket lower than 1 (this will be true only if you've used a "good enough" hashing function that corerctly flattens the distribution of bits in the generated hash value space).
|
|
|
|
|
This not encryption or anything mysterious, it is simply copying unsigned char 8 bit into a 32 bit type by bit wise operations not all the time. NOT encryption.
|
|
|
|
|
The RA8875 is a controller for an 800x480 display I am using in a project.
You can rotate the screen via setting some registers.
There is no option to rotate 90 degrees, only 270, leaving the X axis, and thus text and bitmaps mirrored.
Whoever designed this should be forced to use it.
Real programmers use butterflies
|
|
|
|
|