|
Except that we know *how* they were added. IOW, the get_human function basically isolates everything above 20 bits, multiplies it by 1000 and states that its the terminalID. Ex: 1048577 = terminalId of 1000.
It then takes bits 0-15 (hence the loss of 4 bits) and states that it's the checkNbr. Ex: 1048577 = checkNbr of 1
The two are added together. Ex: 1048577 == 1001
It seems like this should be reversible but I'm not seeing it.
Cheers,
Tom Archer - Archer Consulting Group
"Eat your brussel sprouts, Junior. There are starving Chinese children American programmers that would kill for that food!"
|
|
|
|
|
I think I've got it now - proving that the get_human functoin can be reversed:
unsigned long get_human_check_id(unsigned long id)
{
unsigned long terminalId = (unsigned long)PullTerminalId(id) * 10000;
unsigned long checkNbr = (unsigned)(id & 0xFFFF);
return terminalId + checkNbr;
}
okay, lets break it down:
the terminal id part is in bits 20 and up, then scaled up by 10000
the checknumber is in the lower 16 bits.
So to reverse it you need to take :
terminalid / 10000, then shift it left 20 bits
plus
the checknumber.
My first attempt had roughly the right idea, except for that mask.
Cheers,
Tom Archer - Archer Consulting Group
"Eat your brussel sprouts, Junior. There are starving Chinese children American programmers that would kill for that food!"
|
|
|
|
|
So to reverse it you need to take :
terminalid / 10000, then shift it left 20 bits
plus
the checknumber
where do you get the checknumber ?
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
Check number is bits 0-15 (id & 0xFFFF)
Therefore,
* terminalId is bits 20 and above (multiplied by 1000)
* checkNbr is bits 0-15
The only bits lost are bits 16-19, which are never used.
Cheers,
Tom Archer - Archer Consulting Group
"Eat your brussel sprouts, Junior. There are starving Chinese children American programmers that would kill for that food!"
|
|
|
|
|
Tom Archer wrote:
terminalId is bits 20 and above (multiplied by 1000)
but those bits are shift down 20 (which is equivalent to division by 1048576). they're now bits 0..12 of terminalId.
* checkNbr is bits 0-15
and those two groups of bits are combined by the addition step. they don't occupy distinct bits in the result.
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
That's why the programmer multiplies terminalId by 1000; so that he can add the checkNbr without overlapping the terminalId digits.
Cheers,
Tom Archer - Archer Consulting Group
"Eat your brussel sprouts, Junior. There are starving Chinese children American programmers that would kill for that food!"
|
|
|
|
|
|
The original function is many-to-one, so there may be multiple possible answers when you invert it. For example, the original ids of 43920, 2000000, 2121072, 3159648, and 4198224 all yield a human_check_id of 43920 (with terminalIds of 0, 10000, 20000, 30000, and 40000, respectively).
|
|
|
|
|
Don't think so that it is possible! B'caz you are using and operation on the number. Actually you think as you have 2 numbers of 2 byte each and you are converting them to one number. But we can do the reverse, i.e. for x+y = 5, we can't say that x & y will be what?
http://www.priyank.in/
|
|
|
|
|
You can't reverse the process, cause here:
unsigned PullTerminalId(unsigned long id)
{
return ((unsigned)(id >> 20));
}
You potentially loose information, u can't just automagically make it reappear.
id >> 20 makes the 20 rightmost bits of the unsigned long integer go down a black hole.
Kuniva
--------------------------------------------
|
|
|
|
|
I agree with you both - this is Tom Archer by the way; CP keeps logging me out since I changed my email addr
However, I wanted to verify that with others before telling the client that.
|
|
|
|
|
You can't. It's a one-way algorithm because data gets lost...
First there is a shift right that will "kill" 20 bits, and then the upper 16 bits get lost by the and operation. Additinally there is a addition, which makes it almost impossible to find out what the original summands had been.
Don't try it, just do it!
|
|
|
|
|
Hi
I need to use the AllowSetForegroundWindow method, available since Windows ME.
I downloaded the last Platform SDK, and installed Visual Studio .NET 2002 because the new libraries aren`t compatible with VC6.
The problem is that when i build the project it still give me the error "undeclared identifier" with the AllowSetForegroundWindow method...
Then I added the compiler options
/D"_WIN32_WINNT>=0x0502"
/D "WINVER>=0x0502"
but im still getting the error.
The Project directories are pointing to the platform SDK path...
I dont know what else do.
Any advice is welcomed
Thanks
|
|
|
|
|
Find the declaration of AllowSetForegroundWindow in the header file and look at the #ifdef statements... that's the easy way to find out what is making trouble.
Don't try it, just do it!
|
|
|
|
|
i did what you said, and this is what it say...
#if(_WIN32_WINNT >= 0x0500)
WINUSERAPI
BOOL
WINAPI
AllowSetForegroundWindow(
__in DWORD dwProcessId);
so... setting /D "_WIN32_WINNT >= 0x0500" should do it work... but it doesn`t
|
|
|
|
|
The method EndMenu, implemented in the same release that AllowSetForegroundWindow works...
I hate Microsoft
|
|
|
|
|
I see that EndMenu() is governed by WINVER having a value >= 0x0500. By default, it has a value of 0x0501 so it satisifes the (preprocessor's) condition.
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
|
|
|
|
|
Kharfax wrote:
/D"_WIN32_WINNT>=0x0502"
/D "WINVER>=0x0502"
This won't work. You can't use the comparison operator in place of the the assignment operator.
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
|
|
|
|
|
I don`t know, that is what Microsoft says that should be defined in
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowfunctions/allowsetforegroundwindow.asp
I tried just using the assignament but still doen`t work :S
|
|
|
|
|
Kharfax wrote:
I don`t know, that is what Microsoft says that should be defined in
There's nothing on the link that you provided that indictaes the required values of WINVER or _WIN32_WINNT . The only requirement I found was in winuser.h which indicates that _WIN32_WINNT must have a value >= 0x0500. To see what value it does have, you'll need to put in a few lines of code. The easiest way would be to add the following at the earliest possible moment (e.g., right inside of main() or WinMain() ):
char s[8];
sprintf(s, "%#x", _WIN32_WINNT); Then set a breakpoint on that statement and check the value of s .
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
|
|
|
|
|
|
Did you try using a debugger tool?
|
|
|
|
|
Just because no one responded to your post does not mean that no one (here) knows the answer. Perhaps the right person did not read your post.
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
|
|
|
|
|
yes, Bob! i surely tried to debug the code by using the VC++ built-in debugger.
and DC! how can i make my msgs accessible for ones who know and want to answer?
thanks for your attention
|
|
|
|
|
ilostmyid2 wrote:
and DC! how can i make my msgs accessible for ones who know and want to answer?
That's the $64,000 question! Even if you posted your question at a time when the VC++ forum is most busy, there is no guarantee that your post will be read. It's a crap shoot at best. Good luck!
From my experience, the post's subject must be meaningful and terse. The post's body must be short, relevant, and to the point. Folks don't like spending their free time wading through meaningless code snippets, comments, etc. only to find the poster wanted something entirely different. I also don't like threads to drag on past a half dozen posts or so. By that time the original intent has been lost and you end up on several other tangents instead.
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
|
|
|
|