Mar. 7th, 2010

juan_gandhi: (Default)
В моей френдленте одно время было дикое количество френдов, которые с любовными художественными детальками пишут о всякой херне. То футбольный матч анализируют, как будто это Вековая Борьба Добра Со Злом, то описывают кусочки газеты вмёрзшие в мартовский снег, встречных пешеходов (чаще пешеходок) в развевающихся желтых плащах с кровавым подбоем и каким-то особенным выражением лица, и т.д. и т.п.

И наконец что-то мне это дело надоело. Контента хочется, контента. А контента-то как раз что-то маловато, кроме как в компьютерщине...

вот хотите изложу вычитанный в CACM смешной способ делегировать внешним процессорам вычисления, но при этом не раскрывать данных - так что операции выполняются прямо над зашифрованными данными, а после расшифровки клиентом результат получается таким, как если бы нужные операции провели над незашифрованными данными?
juan_gandhi: (Default)
Алисе нужно посчитать ковариационную матрицу, но у неё не хватает вычислительных мощностей. Мошности есть у Боба, но Алиса не доверяет Бобу свои данные. Как быть?!

Вот решение, которое я вчера в машине вычитал в CACM, который мне присылают в попытках уговорить меня заплатить им 400 баксов за членство и библиотеку, и поддержать их рэкет и ксенофобию (чуть не в каждом номере читаешь о вреде иммигрантов).

Прежде всего, всякую операцию над числами да и вообще можно представить в виде операций над битами; а операций над битами не так много; и если биты представить в виде чисел по модулю 2, то XOR есть сложение, а конъюнкция есть умножение. Остальное выводится.

Теперь нам надо биты зашифровать и передать Бобу, вместе с программой.

Для шифрования используем одно секретное число p > 2. Бит шифруем так:
f(b) = (r1 * 2) + r2 * p + b,

где r1 и r2 - случайные положительные целые числа, причём r1 < p/2.

Восстановить b просто: b = (f(b) % p) % 2.

Понятное дело, что сложение и умножение при таких операциях сохраняется, так что

f-1(f(a) * f(b)) = a * b
f-1(f(a) + f(b)) = a + b


Убиваем двух зайцев - и данные не раскрыты, и Бобу сервер загрузим по самое немогу.

Ну самом деле, конечно, вместо 2 везде можно подставить 256, и выйдет то же самое.

Всё просто, правда? В CACM это описание занимает страниц шесть, с хитрыми формулами и примерами из ювелирной промышленности.
juan_gandhi: (Default)
Many many years ago people were writing their code mostly in Fortran, but also in PL/I. They were told by their teachers not to use too many functions or subroutines, because each call and return is very expensive, compared to plain goto statement.

So the brave programmers managed to write functions or subroutines several thousand lines long; these people were considered smart and very important, compared to the junior kind who only could write a hundred or two lines in one function or subroutine.

Then something bad started happening: the code did not work. Or it did work until you start changing it. As a result, two pрilosophies were born:
1. Do not change anything;
2. Write structured code.

Structured programming consisted of using functions of reasonable sizes with reasonable structures. No jumps into the middle of a loop, no jumps out of looзs into another loop or into a conditional statement; no exits out of the middle of your subroutine.

Then, later, it was discovered that it is just goto statement that should be blamed. So people started setting limitations, depending on their taste and creativity.

- do not goto inside another subroutine;
- do not goto ito a loop or a condition;
- do not goto upstream.

The idea of totally abandoning goto was considered too extremist: how else can we make sure that we have only one exit out of a subroutine or a function?

Well then, why do we need just one exit? There were two reasons:
- it was really hard to set breakpoints on all the exits scattered over half a thousand lines;
- how about releasing resources, like closing files, etc?

So it was decided, more or less unanimously, that we have to a) maintain some kind of "response" or "result" code, and b) goto the bottom of our subroutine and exit from there, using the "result code" to decide whether we should do something to close up our activity.

Since later goto was more and more discouraged (although you can find a goto in Java libraries source code), the kosher solution was suggested that was keeping some kind of integer shitLevel flag; everywhere in your code you are supposed to check the level, and if it is close to the fan, you should proceed without doing anything.

This ideology penetrated into Pascal, C, C++, and, later, Java. And only later people started thinking about structuring their code better.

Like making it smaller.

Besides, some languages have finally block that can be used to neatly close all the streams that may remain open.

These two changes, much smaller code and finally block make "single exit" ideology meaningless. Why does one need a specific variable to pass around if we can just return it? If the whole method is half a screen, is it really hard to find other exit points? Is not it safer to use finally that will release your resources in any case, as opposed to that bottom of the method that may never be reached. Just look at this:
   public final static void doit() {
        try {
            throw new NullPointerException("npe");
        } finally {
            System.out.println("Finally!");
        }
    }

Here is basically the same argument, specifically for Java.

Profile

juan_gandhi: (Default)
Juan-Carlos Gandhi

May 2025

S M T W T F S
    1 2 3
456 7 8 9 10
11 121314151617
181920 21 222324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 23rd, 2025 04:29 am
Powered by Dreamwidth Studios