web-dev-qa-db-ja.com

このコードはインドの地図をどのように生成しますか?

このコードは、インドの地図を印刷します。どのように機能しますか?

#include <stdio.h>
main()
{
    int a,b,c;
    int count = 1;
    for (b=c=10;a="- FIGURE?, UMKC,XYZHello Folks,\
    TFy!QJu ROo TNn(ROo)SLq SLq ULo+\
    UHs UJq TNn*RPn/QPbEWS_JSWQAIJO^\
    NBELPeHBFHT}TnALVlBLOFAkHFOuFETp\
    HCStHAUFAgcEAelclcn^r^r\\tZvYxXy\
    T|S~Pn SPm SOn TNn ULo0ULo#ULo-W\
    Hq!WFs XDt!" [b+++21]; )
    for(; a-- > 64 ; )
    putchar ( ++c=='Z' ? c = c/ 9:33^b&1);
    return 0;
}
168
narayanpatra

長い文字列は、単にASCIIに変換されたバイナリシーケンスです。最初のforステートメントは、bを10から開始し、[b+++21]文字列の後に31が生成されます。文字列を配列として扱うと、オフセット31は文字列の「実際の」データの開始点です(指定したコードサンプルの2行目)。コードの残りの部分は、ビットシーケンスを単純にループし、1と0を!と空白に変換し、一度に1文字を出力します。

難読化されていないバージョン:

#include "stdio.h"
int main (void) {
    int a=10, b=0, c=10;
    char* bits ="TFy!QJu ROo TNn(ROo)SLq SLq ULo+UHs UJq TNn*RPn/QPbEWS_JSWQAIJO^NBELPeHBFHT}TnALVlBLOFAkHFOuFETpHCStHAUFAgcEAelclcn^r^r\\tZvYxXyT|S~Pn SPm SOn TNn ULo0ULo#ULo-WHq!WFs XDt!";
    a = bits[b];
    while (a != 0) {
        a = bits[b];
        b++;
        while (a > 64) {
            a--;
            if (++c == 'Z') {
                c /= 9;
                putchar(c);
            } else {
                putchar(33 ^ (b & 0x01));
            }
        }
    }
    return 0;
}

の 変な 賢い部分はputcharステートメントにあります。最初のputcharを取得します。 ASCII 'Z'は10進数で90なので、90/9 = 10は改行文字です。 2番目の場合、10進数33はASCII for '!'。 33の下位ビットを切り替えると、32が得られます。これは、スペースを表すASCIIです。これにより、!は、bが奇数の場合に印刷され、bが偶数の場合は空白スペースが印刷されます。コードの残りの部分は、単に「ポインタ」aを文字列内で移動するためにあります。

154
bta

基本的に、文字列はイメージの run-length encoding です。文字列内の交互の文字は、スペースを描画する回数と感嘆符を連続して描画する回数を表します。このプログラムのさまざまな要素の分析は次のとおりです。

エンコードされた文字列

この文字列の最初の31文字は無視されます。残りには、画像を描画するための指示が含まれています。個々の文字は、連続して描画するスペースまたは感嘆符の数を決定します。

ループの外側

このループは、文字列内の文字を調べます。反復ごとにbの値が1増加し、文字列内の次の文字がaに割り当てられます。

ループの内側

このループは、個々の文字を描画し、行末に達するたびに改行を描画します。描画される文字の数はa - 64cの値は10から90になり、行末に達すると10にリセットされます。

putchar

これは次のように書き換えることができます。

++c;
if (c==90) {       //'Z' == 90
    c = 10;        //Note: 10 == '\n'
    putchar('\n');
}
else {
    if (b % 2 == 0)
        putchar('!');
    else
        putchar(' ');
}

bが偶数か奇数か、または必要な場合は改行に応じて、適切な文字を描画します。

89
interjay