Category Archives: Tricks

Use Google Authenticator with Microsoft’s

Two-step authentication is the technology to use everywhere as much as possible, to prevent identity and data theft. Many online services, including Dropbox, LastPass, Facebook, are using Google’s Authenticator app. It generates random time-dependent one-time codes that should be entered in the process of the two-factor authentication.

Microsoft’s service also supports the 2-step authentication. However, by default Microsoft wants you to use its own app to generate the one-time codes. It does not make much sense to use it, if you are using Google Authenticator (GA) for all other services. Luckily, Microsoft is smart enough to support GA as well, just in a little hidden, even though simple, manner. Here is how to set it up:

  1. “Add a new identity verification app”
  2. Choose “Android”, press “Next”
  3. (If you now choose “Install the app from the Google Play Store.”, you’ll be offered to install a Microsoft app.) DO NOT DO IT.
  4. At the bottom, there is a line: “Android device not compatible? Try this app instead.” It is a link to the Google Authenticator. Click it.
  5. On the next page, a QR-code for Google Authenticator is shown. Scan it with “Set up account” function in Google Authenticator, verify the code and you are good to go.

Getting file checksum on Synology

cksum utility can calculate the file checksum using 3 different algorithms. The third one is the well-known CRC32.

  • CRC32 of a single file: cksum -o3 filename
  • CRC32 of all files in the current directory: cksum -o3 *

To verify the checksum in Windows, I recommend using HashTab. After installing it, just check the proerpties of a file and compare the CRC32 value returned by HashTab to the value calculated by cksum. Note that HashTab shows CRC32 as a hex number while cksum shows a decimal value; you can use an online converter to compare the two values.

Example (for some file on my Synology):

ds414> cksum -o3 mrr40320.JPG
946866417 14531 mrr40320.JPG

The first number returned by cksum is the CRC32 value, the second the file size in bytes.

Value returned by HashTab for this file is 387008F1 which is the same as 946866417 returned by cksum.

Does anybody know what the 1st and the 2nd algorithms of cksum are? 

Create a Zemax 64 bit DLL

Zemax would normally publish such article in its Knowledge Base. But I think it should be significantly improved (outdated articles should be removed/rewritten, search should be improved, articles should be tagged and linked to each other, user comments should not get lost etc.), and until it is I’ll just publish my notes here.

One of the ways to expand Zemax functionality is by creating custom DLLs for objects, scattering, material, surface etc. Unfortunately, you’ll need something beyond basic knowledge on how to create a DLL in the IDE/compiler of your choice. Unless your DLL looks exactly the way Zemax expects it to look, the program will just ignore it, without any feedback. After some struggling, I’ve managed to make Zemax accept my DLL, and I list the required steps below, with some comments.

As the starting point, I’ve used the C:\Program Files\Zemax\DLL\GradientIndex\grin1.c file provided by Zemax. I also tested this procedure with C:\Program Files\Zemax\DLL\SurfaceScatter\TwoGaussian.c.

Here are the steps needed to make Zemax 64 accept your DLL. The IDE I used was the free MS Visual Studio Express 2013 for Desktop.

  1. Create a new solution in VS. Create a new Visual C++ > Win32 > DLL project in it (
  2. Since Zemax is x64, we need a 64 bit DLL. Go to configuration manager and create a new x64 platform. Set it to active.
    Note: To have it in VS 2010, see (something should be downloaded).
  3. Switch compilation mode to Release. Set Project > Properties (Alt + F7) > Configuration Properties > Linker > Debugging > Generate Debug Info for Release/x64 to NO (
  4. In Project > Properties > Configuration Properties > C/C++ > Preprocessor, add at the end of Preprocessor Definitions:


  5. In Project > Properties > Configuration Properties > C/C++ > Precompiled Headers, set Precompiled Header to an empty value (it can be Yes be default). Taken from
  6. Note the
    extern "C"

    lines I added to the code. This comes from
    This issue is also addressed (and explained in more details) here:
    This command is only needed if the the source file has the .cpp extension. For .c it is not needed.

  7.  The DLL should be copied to C:\Program Files\Zemax\DLL. It requires Administrator rights on the computer.Note that the output DLL is in
    rather than
    I don’t know why.

    The following steps are optional:

  8. Note that I removed the
    int __declspec(dllexport) APIENTRY UserGrinDefinition(double *data);
    int __declspec(dllexport) APIENTRY UserParamNames(char *data);

    lines at the top. It also comes from the fact that they are not there in

  9. To check why Zemax could not see the functions at first, I used the dumpbin tool.
    It should be run from VS’s Command Line, which I could find nowhere. I’ve found how to add it to Tools here:
    The required vcvarsall.bat file could be found in my case in C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC, although I am working with Visual Studio Express 2013. Not sure why.
    With this set up, I could do dumpbin /EXPORTS testDll.dll in the x64/release directory and get:

    C:\Users\xxx\x64\Release>dumpbin /EXPORTS testDll.dll
    Microsoft (R) COFF/PE Dumper Version 12.00.21005.1
    Copyright (C) Microsoft Corporation. All rights reserved.
    Dump of file testDll.dll
    File Type: DLL
    Section contains the following exports for testDll.dll
    00000000 characteristics
    536A6A96 time date stamp Wed May 07 19:17:10 2014
    0.00 version
    1 ordinal base
    2 number of functions
    2 number of names
    ordinal hint RVA name
    1 0 00001010 UserGrinDefinition
    2 1 00001270 UserParamNames
    1000 .data
    1000 .pdata
    1000 .rdata
    1000 .reloc
    1000 .rsrc
    1000 .text
  10. Note that if the DLL is compiled with Visual Studio >2010, it cannot be used on computers with only 2010 distributables. In this case, the distributable DLL can be
  11. statically linked to the DLL, thus removing the dependence. This is done in VS 2013 in Project Properties (Alt + F7) > Configuration Properties > C/C++ > Code Generation > Runtime Library,
    which should be set to Multi-threaded (/MT) from the default Multi-threaded DLL (/MD).

With these modifications, Zemax accepted the DLL and could read the parameter names. I have not tried any calculations so far.

Full source code of the final file (testDll.cpp):

#include <windows.h>
#include <math.h>
#include <string.h>

Written by Kenneth E. Moore
May 11, 2000

Modified January 24, 2005 to support rectangular periodic arrays

Modified 2014-05-07 by Kotya Karapetyan as a test Zemax 64 DLL project. Renamed to testDll.cpp.

BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
   return TRUE;

extern "C" // taken from, is needed to remove C++ symbol decoration, see

    int __declspec(dllexport) APIENTRY UserGrinDefinition(double *data)
        double r, r2, index, N, A, B, x, y, dx, dy;
        N = data[10];
        A = data[11];
        B = data[12];
        dx = data[13];
        dy = data[14];
        x = data[1];
        y = data[2];

        if (dx > 0 && dy > 0)
            // adjust to center of array
            if (x > +0.5*dx) x -= dx*(double)ceil(+(x - 0.5*dx) / dx);
            if (x < -0.5*dx) x += dx*(double)ceil(-(x + 0.5*dx) / dx);
            if (y > +0.5*dy) y -= dy*(double)ceil(+(y - 0.5*dy) / dy);
            if (y < -0.5*dy) y += dy*(double)ceil(-(y + 0.5*dy) / dy);

        r2 = x*x + y*y;
        r = sqrt(r2);

        index = N + A*r2 + B*r;
        data[6] = index;

        if (index < 1.0)
            return -1;

        /* now the derivatives, note they are multiplied by index */
        data[7] = 2.0*A*x*index;
        data[8] = 2.0*A*y*index;
        if (B != 0.0 && r > 0.0)
            data[7] += B*x*index / r;
            data[8] += B*y*index / r;
        data[9] = 0.0;
        return 0;
    int __declspec(dllexport) APIENTRY UserParamNames(char *data)
        /* this function returns the name of the parameter requested */
        int i;
        i = (int)data[0];
        strcpy(data, "");
        if (i == 1) strcpy(data, "N0");
        if (i == 2) strcpy(data, "Nr2");
        if (i == 3) strcpy(data, "Nr1");
        if (i == 4) strcpy(data, "Array dx");
        if (i == 5) strcpy(data, "Array dy");
        if (i == 6) strcpy(data, "K"); // added by Kotya for testing 2014-05-07
        return 0;


See also related Knowledge Base articles: How to compile an extension using MS Visual Studio Express 2012Compiling a 64-bit Application in Microsoft Visual Studio Express 2010 (note: I haven’t checked them for correctness).

Paste pure text in Windows


Years ago, text could only be copied in Windows between the programs as a plain text. That is, only the content, without the format. Today the situation has improved changed and in many programs now when you copy and paste the text, you do so together with the format, whatever it may be.


In my opinion, this is a really poor approach from the user experience perspective. You should use styles to control the look of your text, so the text properties should not be connected to its content. One should really move around the text, not the look. (Word actually does it pretty neatly, by moving the style rather than the look of the text. The problem however is still there if you copy & paste the text from Word to, say, Excel.)

Another problem with moving the text properties around is that sometimes it is really not what you want. Have you ever tried to copy the content of a web page and paste it into Word? You know what happens. Word tries to keep the whole structure of the web page and transfer it to your document. The problem is that web pages are formatted inherently differently than the paper documents. Adding the structure of a web page to a text document means adding numerous redundant elements, such as tables, to your document. Besides, you just wanted the content, the text.


In Google Documents with Windows + Chrome, you can now press Ctrl+Shift+V. For other OS and browsers, see here.

In MS Office, use the Paste Special command. And if you do not like using it all the time, the PureText program comes to help. It is beautifully simple, tiny, and does not require installation. You can assign a new combination for pasting text-only (such as the default Windows+V or Google-like Ctrl+Shift+V) or overrule the standard Ctrl+V. The only two drawbacks are that the program needs admin rights to be run and is not as fast as Windows own clipboard.

Set UTF-8 as default encoding in Notepad

While the majority of power users will recommend to switch from Notepad to the wonderful Notepad++ or Notepad 2, it is still useful to make the original Windows Notepad save texts in UTF-8 by default. 

First, ANSI, which is the default Notepad encoding) is outdated. There is no benefit in saving files in ANSI over saving them in UTF-8. So why not do it properly.

Second, occasionally I want to have the simplicity of Notepad and still be able to use symbols outside the ANSI standard.

So here is how to do it (solution taken from Microsoft Community; note that you need the admin rights to do it):

  1. Start Notepad, do not type anything, do File > Save As, choose UTF-8 encoding and save the file somewhere as TXTUTF-8.txt.
  2. Copy TXTUTF-8.txt to c:\windows\shellnew.
  3. Run regedit (registry editor) and navigate to HKEY_CLASSES_ROOT\.txt\ShellNew.
  4. Right click in the right window > New > “String Value” and rename it to FileName.
  5. Double click on “FileName” and put TXTUTF-8.txt into “Value data:” field and press OK.

Now the default encoding in Notepad is UTF-8.

Convert PDF for Kindle

Normally, you can just select and copy text in PDF and paste it to a text file. Then save in UTF-8 encoding and put the file on the Kindle. It’s hard with big documents (aka books) though.

Another way is to save PDF as text (available in Acrobat Reader). The disadvantage is a complete loss of the document structure. The text is readable but not looking nice.

Recently I’ve found and tested on a 270+ page book this service: It’s free and in my case has created a very nicely looking mobi file, which Kindle can read.