Archive
Programmer testing miracle products, the green coffey diet!
Facebook and other media is packed to the brim with diets and products that are supposed to help with lose weight. They are so annoying that I decided to test and blog about one of them, because I firmly believe they are wrong. I find it so sad  that friends (primarily women) throw away money on these products, because ultimately, there is only one way to get a better body and that is to work out! So today I decided to give one of these miracle diets a critical, real-life test by a programmer which, in most likelihood, is used to be being far more critical than the aunts, cousins and sisters of this world.
But, I am going to be fair. If this works (which I highly doubt) I have agreed to wear “the norwegian pants” (google that) for a whole workday at the office. Although I don’t think that will happen anytime soon.

Or just work out for 1 hour a day…
What is acclaimed
According to the commercials (both the one circulating on Facebook, G+, radio and television) the 100% guaranteed results of taking 2 capsules of raw green-coffey a day, and im extrapolating from different sources here, are:
- Firmer breasts
- Tighter thighs (Robin hood style?)
- Lose at least 4 kilos of fat in 30 days (not body weight, but fat!)
- More energy
- Overall happier with less mood swings
- Less menstrual pain
- Smother and more vibrant skin
Initial thoughts
The concept of firmer breasts freaks me out right off the bat, but in the name of science and computing im willing to grow a pair for the team. Although it would be quite a miracle if i evolve a pair of knockers over the next month (and somewhat materials for a horror movie; pictures of the poor due in Fight Club immediately springs to mind).

The norwegian stuff
Also, the box contains 60 tablets – meaning a 30 day program – which incidentally means you violate the “trial” period of you actually complete the diet! Meaning of course that you wont get a penny back because your complaint is made on wrong assumptions.
Debugging the content
My first impression of this product is, naturally, that it contains quite high doses of caffeine. Which is known for the following effects:
- Tightens blood arteries, giving a false experience of firmness
- Causes the body to expel excess water
- Makes you feel more awake
- Is used in painkillers
- Causes the liver to produce more gall, leading to more acidic stomach content, which results in more frequent toilet visits
So to sum up, the product more or less promises to deliver exactly the same (if not less) than a cheaper off the shelf pre-workout formula!
Be that as it may – the ad claims that you are to lose 4 kilos of fat, not water — so this will be interesting! Having taken 2 capsules I have already been to the toilet 2 times in 1 hour, so I know where this is going…
[To be continued..]
Using the crypt unit for something useful
Right, I posted the full crypto unit yesterday, but I didn’t have time to post an example of how to use it. So this time we are going to have some real-life practical examples.
How does this key stuff work?
We are all used to passwords and security these days, but there are a few things that have changed since the golden days of home-made services and DIY websites. Most notably is the fact that you should never store passwords at all. If you think back 5-8 years ago, it would have been perfectly valid for a webservice or a database driven website to store usernames and passwords in a database table. But should someone gain access to your database, they could in fact rob your database of passwords and ruin everything.
The solution? Dont store passwords. You store a hash of a password. A hash is just a number that is generated from analysing a piece of data, it’s sometimes also called a checksum. The important part about a hash is that it will generate the same number exclusively when the data matches. As you can imagine, it’s almost impossible to guess a password from a hash-number.
Another thing to note about key-pairs is that they are not designed to encrypt large sections of data. They are designed to encrypt small things (passwords) and have a limit ranging from 256 to 512 bytes – meaning somthing like 128 unicode characters. Encryption of files and streams is done by generating a hash from an encrypted password – and using that hash as the key for a common cipher like RC4 or Blowfish. These extra steps makes it more or less impossible to decode your data without the absolute and concrete original information.
Here is one way of generating a a portable, encrypted file:
- Generate a hash from a password
- Generate a cipher key-set
- Encrypt the hash using the public key
- Save the encrypted hash to the target-stream
- Save the public key to the target-stream
- Encrypt the password-hash using the private key
- Use encrypted hash as a key-stream for encrypting the “real” data
- Save encrypted data to the target-stream
This creates a dual-key lock. You need both the original private-key and password to decipher the data. Even if you steal the original key-set or gain the original password, the data remains useless without both. By de-coupling these two factors and only providing the public key, another person can only verify that the file belongs to you (by first generating a hash of your password, then decrypting the provided hash using the public key and comparing it), but you still cant read the content of such a file without the private key. This is more or less how secure document transportation works, where you can checkout a document anywhere in the world with a smart-card and personal password. The private key is stored on the card and without both items the data remains unreadable.
How you chose to play around with these schemes is up to you. In some cases rolling your own security is better than buying a solution, because the less that is known about a scheme – the harder it will be to crack.
Generating keys
To generate a key-pair you would write:
procedure TForm1.Button3Click(Sender: TObject); var mPrivate: TStream; mPublic: TStream; mTemp: String; begin if TCryptoAPI.rsaMakeKeys(mprivate,mPublic) then begin try if TCryptoAPI.rsaKeyToBase64(mPrivate,mTemp) then showmessage(mTemp); if TCryptoAPI.rsaKeyToBase64(mPublic,mTemp) then showmessage(mTemp); finally mPrivate.Free; mPublic.Free; end; end; end;
I included two helper functions for turning the streams into Base64 encoded strings, simply called rsaKeyToBase64() and rsaBase64ToKey(), its is sometimes easier to transport the keys as text (and also to display the results while working).
Encrypting a stream
procedure TForm1.Button2Click(Sender: TObject); var mKey: TStringStream; mText: String; mSrc: TStringStream; mdst: TStringStream; begin //Replace mSrc with your filestream mSrc:=TStringStream.Create; try mDst:=TStringStream.Create; try if TCryptoAPI.rsaBase64ToKey("Base64 key text here",TStream(mKey)) then begin try //Remove this obviously when encrypting a file or a memory stream mSrc.WriteString("Text/data to encrypt here"); mSrc.Position:=0; if not TCryptoAPI.rsaCryptStream(mKey,mSrc,mDst) then RaiseLastOSError; finally mKey.Free; end; end; finally mDst.Free; end; finally mSrc.Free; end; end;
To decrypt a stream, do the same as above but call TCryptoAPI.rsaDecryptStream() instead.
Voila! Next we will implement the code for encrypting passwords with the crypto-key-set!
Arrrgh….
Im gonna fix this certificate thing once and for all. Porting this crap to Delphi ASAP!
// Sign void Sign(wchar_t * SignerName, wchar_t * DataFileName, wchar_t * SignatureFileName) { // Variables HCERTSTORE hStoreHandle = NULL; PCCERT_CONTEXT pSignerCert = NULL; HCRYPTPROV hCryptProv = NULL; DWORD dwKeySpec = 0; HCRYPTHASH hHash = NULL; HANDLE hDataFile = NULL; BOOL bResult = FALSE; BYTE rgbFile[BUFSIZE]; DWORD cbRead = 0; DWORD dwSigLen = 0; BYTE * pbSignature = NULL; HANDLE hSignatureFile = NULL; DWORD lpNumberOfBytesWritten = 0; wprintf(L"SIGNING\n\n"); // Open the certificate store. hStoreHandle = CertOpenStore( CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, CERT_PERSONAL_STORE_NAME ); CheckError((BOOL)hStoreHandle, L"CertOpenStore....................... "); // Get signer's certificate with access to private key. do { // Get a certificate that matches the search criteria pSignerCert = CertFindCertificateInStore( hStoreHandle, MY_TYPE, 0, CERT_FIND_SUBJECT_STR, SignerName, pSignerCert ); CheckError((BOOL)pSignerCert, L"CertFindCertificateInStore.......... "); // Get the CSP, and check if we can sign with the private key bResult = CryptAcquireCertificatePrivateKey( pSignerCert, 0, NULL, &hCryptProv, &dwKeySpec, NULL ); CheckError(bResult, L"CryptAcquireCertificatePrivateKey... "); } while ((dwKeySpec & AT_SIGNATURE) != AT_SIGNATURE); // Create the hash object. bResult = CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hHash ); CheckError(bResult, L"CryptCreateHash..................... "); // Open the file with the content to be signed hDataFile = CreateFileW(DataFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL ); CheckError((hDataFile != INVALID_HANDLE_VALUE), L"CreateFile.......................... "); // Compute the cryptographic hash of the data. while (bResult = ReadFile(hDataFile, rgbFile, BUFSIZE, &cbRead, NULL)) { if (cbRead == 0) { break; } CheckError(bResult, L"ReadFile............................ "); bResult = CryptHashData( hHash, rgbFile, cbRead, 0 ); CheckError(bResult, L"CryptHashData....................... "); } CheckError(bResult, L"ReadFile............................ "); // Sign the hash object dwSigLen = 0; bResult = CryptSignHash( hHash, AT_SIGNATURE, NULL, 0, NULL, &dwSigLen ); CheckError(bResult, L"CryptSignHash....................... "); pbSignature = (BYTE *)malloc(dwSigLen); CheckError((BOOL)pbSignature, L"malloc.............................. "); bResult = CryptSignHash( hHash, AT_SIGNATURE, NULL, 0, pbSignature, &dwSigLen ); CheckError(bResult, L"CryptSignHash....................... "); // Create a file to save the signature hSignatureFile = CreateFileW( SignatureFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); CheckError((hSignatureFile != INVALID_HANDLE_VALUE), L"CreateFile.......................... "); // Write the signature to the file bResult = WriteFile( hSignatureFile, (LPCVOID)pbSignature, dwSigLen, &lpNumberOfBytesWritten, NULL ); CheckError(bResult, L"WriteFile........................... "); // Clean up and free memory. free(pbSignature); CloseHandle(hDataFile); CloseHandle(hSignatureFile); bResult = CryptDestroyHash(hHash); CheckError(bResult, L"CryptDestroyHash.................... "); bResult = CertFreeCertificateContext(pSignerCert); CheckError(bResult, L"CertFreeCertificateContext.......... "); bResult = CertCloseStore( hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG ); CheckError(bResult, L"CertCloseStore...................... "); } // End of Sign
Put a fork in it
Ok, so the basic Quartex IDE prototype is nearing completion. I am going to polish it as much as I can, but focusing more on the features you expect to be working “as in Delphi” rather than going creative and adding something new. Things like search and replace dialogs need to be fast, accurate, responsive and non-modal. Keyboard shortcuts should not collide, visual appearance should be balanced, exposed features in terms of buttons should be intuitive and not dominating;
And last but not least, I want the IDE to fast, flicker free and responsive. Large Delphi applications can sometimes become a bit sluggish, especially if the GUI deploy an abundance of nested TPanels to force the look and feel of things. So I am sticking to as little TPanels as possible, using only standard and very basic VCL components that are available on all platforms.
And if this is ever going to run under firemonkey I need to set up an enable/disable system which mimics the use of actions. I find it hard to believe that so many programmers havent used (or even heard of) actions under Delphi. It is probably the best RAD feature Delphi has to offer over database management and frames. Which is why I havent even considered using Firemonkey for any of my projects, because it feels like taking a step backwards.
Why a new IDE?
The reason the Quartex IDE is important, is because we (the Delphi community) really don’t have an “out of the box” IDE that can be bought/forked and used for new and exciting projects. There is no public research-sandbox where people can experiment with the language, try out new ideas for object pascal and break the rules (so to speak). Everyone has to roll their own with mixed results. This used to be the case for text-editors, until SynEdit came along and unified and perfected “code editing” once and for all.
So the idea is to polish and make the IDE as solid and well written as possible, making sure it remains as agnostic and oblivious to the compiler architecture as possible.
The bridge
The hard part is not “getting it to work”, but rather “getting it to work without mixing apples and pears”. I want the compiler sub-system completely separated from the generic IDE. And I want the IDE to provide its services (editing, debugging, package management etc.) without having to care about “who or what” uses them. I need symbol info, ok – here you go. I need syntax proposals, ok – here you go. If a service is registered and implements the interfaces required things should just work.
The bridge between the ide and the compiler is (as it should be), an intermediate class/interface hierarchy and information layer. So all those cool functions like the ability to display a live overview of classes and methods – should be delivered to the IDE in a uniform way. Completely decoupled from whatever compiler is being used.
The final build
Once the prototype is complete, tested and made rock-solid — I will look into getting it ported. Since there is a bug in FPC generics (which eric has reported several times) the DWScript compiler and runtime cannot be ported to freepascal, which is really sad since that would allow us to target linux, unix, osx (which is a variation of unix) and windows straight out of the box. So we are left with Firemonkey. This really is a problem because synEdit have yet to be ported to that platform, and also actions are not implemented under firemonkey (hence my question to pawel at the firemonkey presentation expo in oslo).
A firemonkey port of synEdit is really, really needed at this point (so if anyone is up for a challenge, there you have it).
Why Actions never made it into Firemonkey
A couple of years back I went to se Pawel Glowacki present Firemonkey for the Norwegian Delphi community in Oslo.
During that meetup two good questions were asked by the audience. The first question was from Halvard Vassbotn, which i seem to recall asked about threading and “what is the point of a 3d spreadsheet”, and the second question was from me – asking if fire monkey supported messages. I already suspected that Firemonkey had no fallback mechanism for messages like Kylix had, but it was a serious question since the majority of Delphi applications rely on (or use) messages as a part of their architecture.
One of the benefits of Delphi over other languages is the introduction of Actions and Action-lists. Using actions to isolate code that can be connected to menu items, buttons and options is a great time saver. And more importantly, to be able to isolate testing of action enable states (should a button be enabled right now?) is really a game changer for RAD development. But for some morbid reason this has been omitted from Firemonkey, leaving people to write “somecomponent.enabled:=true” and “somecomponent.enabled:=False” all over their code. The entire point of actions was to get rid of this old-school problem. To this day C# or Visual Basic has nothing like it – and now Delphi/Firemonkey is taking a step backwards.
Either way, the reason Actions are not supported by Firemonkey because they are based on messages. Which is silly really because a simple callback system hooking into the application idle-time could have solved it. Making Firemonkey much richer in the process.
You must be logged in to post a comment.