• mina86.com

  • Categories
  • Code
  • Contact
  • Java: Stringchar[]

    Do you recall when I decided to abuse Go’s runtime and play with string[]byte conversion? Fun times… I wonder if we could do the same to Java?

    To remind ourselves of the ‘problem’, strings in Java are immutable but because Java has no concept of ownership or const keyword to make true on that promise, Java runtime has to make a defensive copy each time a new string is created or when string’s characters are returned.

    Alas, do not despair! There is another way (exception handling elided for brevity):

    private static Field getValueField() {
    	final Field field = String.class.getDeclaredField("value");
    	field.setAccessible(true);
    	/* Test that it works. */
    	final char[] chars = new char[]{'F', 'o', 'o'};
    	final String string = new String();
    	field.set(string, chars);
    	if (string.equals("Foo") && field.get(string) == chars) {
    		return field;
    	}
    	throw new UnsupportedOperationException(
    		"UnsafeString not supported by the runtime");
    }
    
    private final static Field valueField = getValueField();
    
    public static String fromChars(final char[] chars) {
    	final String string = new String();
    	valueField.set(string, chars);
    	return string;
    }
    
    public static char[] toChars(final String string) {
    	return (char[]) valueField.get(string);
    }

    However. There is a twist…

    Calculating RGB↔XYZ matrix

    I’ve recently found myself in need of an RGB↔XYZ transformation matrix expressed to the maximum possible precision. Sources on the Internet typically limit the precision to a handful decimal places so I’ve performed do the calculations myself.

    What we’re looking for is a 3-by-3 matrix \(M\) which, when multiplied by red, green and blue coordinates of a colour, produces its XYZ coordinates. In other words, a change of basis matrix from a space whose basis vectors are RGB’s primary colours: $$ M = \begin{bmatrix} X_r & X_g & X_b \\ Y_r & Y_g & Y_b \\ Z_r & Z_g & Z_b \end{bmatrix} $$

    PSA: Yes, 64-byte key file is okay

    In an earlier entry I’ve changed generated key file used for disk encryption from 4096 to meagre 64 bytes. I gave no mention of that adjustment considering it unimportant but have since been enquired about security of such a short password.

    Rest assured, a 64-byte key file is sufficient for any symmetric encryption (disk encryption being one example) and anything more does not improve security.

    Go: string[]byte

    Yes… I’ve started coding in Go recently. It lacks many things but the one feature relevant to this post is const keyword. Arrays and slices in particular are always mutable and so equivalent of C’s const char * does not exist.

    On the other hand, strings are immutable which means that conversion between a string and []byte requires memory allocation and copying of the data1. Often this might be acceptable but to squeeze every last cycle the following two functions might help achieve zero-copy implementation:

    func String(bytes []byte) string {
    	hdr := *(*reflect.SliceHeader)(unsafe.Pointer(&bytes))
    	return *(*string)(unsafe.Pointer(&reflect.StringHeader{
    		Data: hdr.Data,
    		Len:  hdr.Len,
    	}))
    }
    
    func Bytes(str string) []byte {
    	hdr := *(*reflect.StringHeader)(unsafe.Pointer(&str))
    	return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
    		Data: hdr.Data,
    		Len:  hdr.Len,
    		Cap:  hdr.Len,
    	}))
    }

    Depending on the length of the strings, the difference in performance might be noticeable:

    PSA: Creating world-unreadable files

    I’ve been reading tutorials on using key-files for disk encryption. Common approach for generating such files is to create it using something similar to head -c 4096 /dev/urandom >key-file and only then change it’s permissions (usually with a plain chmod 400 key-file) to prevent others from reading it.

    Please, stop doing this and spreading that method. The correct way of achieving the effect is:

    (umask 077; head -c 64 /dev/random >key-file)

    Or if the file needs to be created as root while command is run by a different user:

    sudo sh -c 'umask 077; head -c 64 /dev/random >key-file'

    The first method creates the file as world-readable1 and before its permission are changed anyone can read it. The second method creates the file as readable only by its owner from the beginning thus preventing the secret disclosure.

    Generating random reals

    A well known way of generating random floating-point numbers in the presence of a pseudo-random number generator (PRNG) is to divide output of the latter by one plus its maximum possible return value.

    extern uint64_t random_uint64(void);
    
    double random_double(void) {
    	return random_uint64() / (UINT64_MAX + 1.0);
    }

    This method is simple, effective, inefficient and wrong on a few levels.

    Strach

    English version available on The Codeless Code.

    Niedawno przyjęty do świątyni mnich zbliżył się do mistrza.

    — Otrzymałem zadanie dodania kilku nowych funkcji do systemu obsługi zamówień Cesarskiego Szewca, ale nie jestem w stanie zrozumieć, jak on działa. Logika jest rozproszona pomiędzy wiele aplikacji zaimplementowanych przy użyciu najróżniejszych technologii. Zamiast stworzyć wspólne biblioteki, autorzy najzwyklej skopiowali fragmenty kodu pomiędzy różnymi miejscami, często wprowadzając subtelne rozbieżności. Zadania pracujące w tle wyszukują i modyfikują rekordy w bazie danych bez żadnego udokumentowanego powodu. Sama baza danych wydaje się spiskować przeciwko mnie: prosta modyfikacja jednej tabeli może wyzwolić kaskadę zmian w wielu innych.

    Python tips and tricks

    Python! My old nemesis, we meet again. Actually, we meet all the time, but despite that there are always things which I cannot quite remember how to do and need to look them up. To help with the searching, here there are collected in one post:

    TLS is a yes

    An image of Hollywood’s idea of ‘hacking’
    (still from movie Swordfish)

    Let’s Encrypt has left beta and to celebrate, this blog gained TLS support. \o/ If all goes well it’ll become the default including an HSTS header so everyone can benefit from improved privacy.1

    Website move

    Photo of a truck on a road.
    (photo by Ikiwaner)

    Some regular visitors of the web site may be aware that the page used to run on Jogger.pl platform. Some will also be aware that the service closes shop, an act which forced me to move to another hosting.

    In moving the page, I’ve tried to keep old URLs work so even though canonical locations for posts have changed, the old links should result in a correct redirect.

    This is also true for feeds but while Jogger provided customisation options (RSS and Atom, excerpts only, no HTML and posts count), currently only full-content HTML Atom feeds limited to newest ten entries are provided.

    If anything broke for you, please do let me know at mina86@mina86.com.

    I have not yet figured out what to do with comments which is why commenting is currently unavailable. Since I want my whole page to be completely static, I’m planning on using a third-party widget. So far I’ve narrowed the choice down to HTML Comment Box and the new hotness, Spot.IM. Any suggestions are also welcome.

    Graph showing drop in response time from 300 ms to 60 ms

    On the bright side, the page now loads five times faster! Jogger.pl took its sweet time when generating responses. A static page and better optimised infrastructure of my current provider allows to drop response time from 300 to 60 ms.