<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>taichino.com &#187; python</title>
	<atom:link href="http://taichino.com/category/programming/python-programming/feed" rel="self" type="application/rss+xml" />
	<link>http://taichino.com</link>
	<description>永遠のネバーランド</description>
	<lastBuildDate>Sat, 04 Feb 2012 13:33:04 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>[RSAの勉強日記2] Javascriptで暗号化してPythonで復号したい</title>
		<link>http://taichino.com/programming/2667</link>
		<comments>http://taichino.com/programming/2667#comments</comments>
		<pubDate>Sat, 04 Feb 2012 08:21:39 +0000</pubDate>
		<dc:creator>taichino</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[pkcs]]></category>
		<category><![CDATA[RSA]]></category>

		<guid isPermaLink="false">http://taichino.com/?p=2667</guid>
		<description><![CDATA[先日、RSAについて解った気になったと書いたんですけど、実際はあんまり解ってなかったので補足等。やりたいのはクライアントで暗号化した情報をサーバで受けて復号したいという事ですね。 鍵の生成をサーバで行って公開鍵をJSのコードに埋める JS側で公開鍵を使って暗号化したデータをサーバに送る サーバで受け取ったデータをPythonで復号 単純な話なはずだったんですけど、上手く行かずにハマりました。 結論から書くと、PyCryptoモジュールがPKCS#1で規定されているのパディング/アンパディングに対応してなかったので自前でアンパディング処理を追加したら上手く行ったという事ですが、学習をかねてもう少し詳しく書いておきます。 本エントリ中の公開鍵・秘密鍵は以下のものを使用しています。他の鍵を使った場合は文中の値は異なります。 PRIVATE KEY: p=312812244098101569570522771086507368199 q=261732496899955705693539027437044751693 n=81873129708674556552097159647951377728324724985548367405770094930146879610907 d=61350191904775909756579327908681267205274632675124298948670533913070326529385 e=65537 PUBLIC KEY: n=81873129708674556552097159647951377728324724985548367405770094930146879610907 e=65537 結局コード見るのがはやいです。まずはPython側ですが、PyCryptoから暗号化処理部分の抜粋したコードを以下に示します。 # pubkey.pyから抜粋 def encrypt(self, plaintext, K): &#34;&#34;&#34;encrypt(plaintext:string&#124;long, K:string&#124;long) : tuple Encrypt the string or integer plaintext. K is a random parameter required by some algorithms. &#34;&#34;&#34; wasString=0 if isinstance(plaintext, types.StringType): plaintext=bytes_to_long(plaintext) ; wasString=1 if isinstance(K, types.StringType): [...]]]></description>
			<content:encoded><![CDATA[<p>先日、<a href="http://taichino.com/engineer-life/2647" title="RSAの勉強日記">RSAについて解った気になったと書いた</a>んですけど、実際はあんまり解ってなかったので補足等。やりたいのはクライアントで暗号化した情報をサーバで受けて復号したいという事ですね。</p>
<ol>
<li>鍵の生成をサーバで行って公開鍵をJSのコードに埋める</li>
<li>JS側で公開鍵を使って暗号化したデータをサーバに送る</li>
<li>サーバで受け取ったデータをPythonで復号</li>
</ol>
<p>単純な話なはずだったんですけど、上手く行かずにハマりました。</p>
<p>結論から書くと、<a href="https://www.dlitz.net/software/pycrypto/" title="pycryptoモジュール" target="_blank">PyCryptoモジュール</a>がPKCS#1で規定されているのパディング/アンパディングに対応してなかったので自前でアンパディング処理を追加したら上手く行ったという事ですが、学習をかねてもう少し詳しく書いておきます。</p>
<p><span id="more-2667"></span></p>
<p>本エントリ中の公開鍵・秘密鍵は以下のものを使用しています。他の鍵を使った場合は文中の値は異なります。</p>
<pre class="brush: text; gutter: true; first-line: 1; highlight: []; html-script: false">
PRIVATE KEY:
  p=312812244098101569570522771086507368199
  q=261732496899955705693539027437044751693
  n=81873129708674556552097159647951377728324724985548367405770094930146879610907
  d=61350191904775909756579327908681267205274632675124298948670533913070326529385
  e=65537
PUBLIC KEY:
  n=81873129708674556552097159647951377728324724985548367405770094930146879610907
  e=65537
</pre>
<p>結局コード見るのがはやいです。まずはPython側ですが、PyCryptoから暗号化処理部分の抜粋したコードを以下に示します。</p>
<pre class="brush: python; gutter: true; first-line: 1; highlight: []; html-script: false">
# pubkey.pyから抜粋
def encrypt(self, plaintext, K):
    &quot;&quot;&quot;encrypt(plaintext:string|long, K:string|long) : tuple
    Encrypt the string or integer plaintext.  K is a random
    parameter required by some algorithms.
    &quot;&quot;&quot;
    wasString=0
    if isinstance(plaintext, types.StringType):
        plaintext=bytes_to_long(plaintext) ; wasString=1
    if isinstance(K, types.StringType):
        K=bytes_to_long(K)
    ciphertext=self._encrypt(plaintext, K)
    if wasString: return tuple(map(long_to_bytes, ciphertext))
    else: return ciphertext

# _slowmath.pyから抜粋
def _encrypt(self, m):
    # compute m**d (mod n)
    return pow(m, self.e, self.n)
</pre>
<p>直線的で解りやすいコードですね。理解の為にencrypt関数に&#8221;a&#8221;を一文字だけ入れた場合の暗号化の流れを観察すると以下のようになります。</p>
<pre class="brush: text; gutter: true; first-line: 1; highlight: []; html-script: false">
a
=&gt; bytes_to_long (バイト列を数値に)
97
=&gt; _encrypt (中でpow。これがいわゆる公開鍵による暗号化)
(52050588761940096487735844075636185108122635599049953266504222754946145963317L,)
=&gt; long_to_bytes (数値を再度バイト列に)
(&#039;s\x13\x96\xd7\xd3\xaf\x92\xf2V\xa3]\x1d:;9O3\xd2\x91\xb7;&quot;\x16\xde\xe7\xf5 \x8a\xdd\x1d\xcd5&#039;,)
</pre>
<p>バイト列を数値に直してから公開鍵による暗号化を行い、再度バイト列に直しています。復号時はこれを逆順で行うわけですね。(もちろん暗号化処理は秘密鍵による復号処理になります。)ここまでは僕の理解通りの処理になっていて何の問題もありませんでした。</p>
<p>一方でJavascriptで行われていた処理を見てみます。ライブラリは<a href="https://ziyan.info/2008/10/javascript-rsa/" title="RSA module with pure Javascript" target="_blank">コチラのrsa.js</a>を使わせて頂いています。色々検索した結果pemをロードできるのはこれしか見つかりませんでした。下記に対応する部分のコードを抜粋します。</p>
<pre class="brush: javascript; gutter: true; first-line: 1; highlight: []; html-script: false">
encrypt: function($data, $pubkey) {
    if (!$pubkey) return false;
    $data = this.pkcs1pad2($data,($pubkey.modulus.bitLength()+7)&gt;&gt;3);
    if(!$data) return false;
    $data = $data.modPowInt($pubkey.encryptionExponent, $pubkey.modulus);
    if(!$data) return false;
    $data = $data.toString(16);
    $data = Hex.decode($data);
    return Base64.encode($data);
},
pkcs1pad2: function($data, $keysize) {
    if($keysize &lt; $data.length + 11)
        return null;
    var $buffer = [];
    var $i = $data.length - 1;
    while($i &gt;= 0 &amp;&amp; $keysize &gt; 0)
        $buffer[--$keysize] = $data.charCodeAt($i--);
    $buffer[--$keysize] = 0;
    while($keysize &gt; 2)
        $buffer[--$keysize] = Math.floor(Math.random()*254) + 1;
    $buffer[--$keysize] = 2;
    $buffer[--$keysize] = 0;
    return new BigInteger($buffer);
}
</pre>
<p>encrypt関数の冒頭で既に様子が違います。暗号化する前の元のデータにpkcs1pad2とかいう謎の処理をかませて、データが変更されています。そしてpkcs1pad2の関数を見ても何をやっているのか全然解りません。関数名からパディングでもやってんのかな位しかわかりません。わずかな希望を胸に、データの暗号化の流れを見てみます。</p>
<pre class="brush: text; gutter: true; first-line: 1; highlight: []; html-script: false">
a
=&gt; pkcs1pad2 (パディング)
3758866564912349439687065567220758327058221768110629839398887525335105633
=&gt; modPowInt (公開鍵暗号化)
14633336708515644111578124792772238970855809995718279846212374275613915803829
=&gt; toString(16)
205a2cd13e395895de49814ec6f9c424f4622f1ffa722f1c88ee23aa521af0b5
=&gt; Hex.decode
バイト列(HTMLで上手く表示できません)
=&gt; Base64.encode
IFos0T45WJXeSYFOxvnEJPRiLx/6ci8ciO4jqlIa8LU=
</pre>
<p>もしかしたらデータは一致するかもという希望は失われました。全然違ったデータになっていますね。困りましたね。要は一口にRSA暗号化といっても、実装によって暗号化・復号処理以外の部分で、データの扱いに違いがあって必ずしも相互にデータを受け渡せるとは限らないという事ですね。</p>
<p>仕方が無いのでpkcs1pad2関数について調べてみると、PKCSというのは<a href="http://ja.wikipedia.org/wiki/PKCS" title="pkcs in wikpedia" target="_blank">Public-Key Cryptography Standards</a>の略で、公開鍵暗号の分野のRFCのようなもののようです。そしてpkcs1というのはPKCS#1のことで、特定の標準仕様を指していて、この中でパディングの方法についても規定されています。</p>
<p>んじゃあ、このPKCSってどの位採用されてんの？と思うわけですが、ざっと調べた感じ事実上デファクトで、perlやrubyのモジュールでは当然のように対応されています。何故かPythonのPyCryptoだけ対応してないという話のようです。</p>
<p>ちょっと調べてみると<a href="http://kfalck.net/2011/03/07/decoding-pkcs1-padding-in-python" title="PyCryptoでPKCS#1を復号" target="_blank">PyCryptoでPKCS#1のデータ復号するときはこうしろという記事</a>が見つかったので、解決しました。まとめがてらPyCryptoでrsa.jsで暗号化したデータを復号する処理を書いておきます。</p>
<pre class="brush: python; gutter: true; first-line: 1; highlight: []; html-script: false">
import Crypto
from Crypto.PublicKey import RSA
import base64

def pkcs1_unpad(text):
    if len(text) &gt; 0 and text[0] == &#039;\x02&#039;:
        # Find end of padding marked by nul
        pos = text.find(&#039;\x00&#039;)
        if pos &gt; 0:
            return text[pos+1:]
    return None

priv = RSA.importKey(open(&#039;priv.pem&#039;, &#039;r&#039;).read())
data = &#039;aoNFe/Y/Nae0wmeY1DUuMTP4bDe4Tib0/fQZynL7UFc=&#039; # encrypted data from js with base 64 encoded
data = base64.b64decode(data)
data = priv.decrypt(data)
data = pkcs1_unpad(data)    # a
</pre>
<p>以上で、Javascriptで暗号化したデータをPythonで復号できました。○○暗号化と一口に言っても実装によって差異があるというのが解って、まぁ良かったと言えば良かったです。PyCryptoでも早く対応して欲しいところです。あと、pkcs1pad2の&#8221;2&#8243;が何を意味しているのか解らないので、誰か知ってたら教えてください。</p>
]]></content:encoded>
			<wfw:commentRss>http://taichino.com/programming/2667/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RSAの勉強日記</title>
		<link>http://taichino.com/engineer-life/2647</link>
		<comments>http://taichino.com/engineer-life/2647#comments</comments>
		<pubDate>Wed, 01 Feb 2012 15:50:41 +0000</pubDate>
		<dc:creator>taichino</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[技術]]></category>
		<category><![CDATA[RSA]]></category>

		<guid isPermaLink="false">http://taichino.com/?p=2647</guid>
		<description><![CDATA[Javascriptでデータ送る際にデータを暗号化したいなという事で、そうだRSAを使おうと思ったのですが、RSAについて、sshの鍵作る時に出てくる単語で暗号方式？位の理解しかなかったので少し調べてみました。 まず概要の把握ですが、僕は「サルにもわかるRSA暗号」を流してから、「RSA暗号体験入門」を読んだらとりあえず解った気になりました。 次に処理の流れをopensslコマンドで確認してみます。ここでは鍵を生成 => テキストを暗号化 => 復号を確認しました。なお秘密鍵を生成する際のビット数はデフォルトでは512で、普通は1024以上指定するようですが、数が大きくなると確認しづらいので256ビットを指定しています。 $ openssl genrsa -out priv.pem 256 Generating RSA private key, 256 bit long modulus .+++++++++++++++++++++++++++ .................+++++++++++++++++++++++++++ e is 65537 (0x10001) $ openssl rsa -in priv.pem -pubout -out pub.pem writing RSA key $ echo &#34;hello rsa&#34; &#62; hello.txt $ openssl rsautl -encrypt -pubin -inkey pub.pem -in hello.txt -out hello.txt.crypto [...]]]></description>
			<content:encoded><![CDATA[<p>Javascriptでデータ送る際にデータを暗号化したいなという事で、そうだRSAを使おうと思ったのですが、RSAについて、sshの鍵作る時に出てくる単語で暗号方式？位の理解しかなかったので少し調べてみました。</p>
<p><span id="more-2647"></span></p>
<p>まず概要の把握ですが、僕は「<a href="http://www.maitou.gr.jp/rsa/" title="サルにもわかるＲＳＡ暗号" target="_blank">サルにもわかるRSA暗号</a>」を流してから、「<a href="http://www.cybersyndrome.net/rsa/index.html" title="RSA暗号体験入門" target="_blank">RSA暗号体験入門</a>」を読んだらとりあえず解った気になりました。</p>
<p>次に処理の流れをopensslコマンドで確認してみます。ここでは鍵を生成 => テキストを暗号化 => 復号を確認しました。なお秘密鍵を生成する際のビット数はデフォルトでは512で、普通は1024以上指定するようですが、数が大きくなると確認しづらいので256ビットを指定しています。</p>
<pre class="brush: bash; gutter: true; first-line: 1; highlight: []; html-script: false">
$ openssl genrsa -out priv.pem 256
Generating RSA private key, 256 bit long modulus
.+++++++++++++++++++++++++++
.................+++++++++++++++++++++++++++
e is 65537 (0x10001)
$ openssl rsa -in priv.pem -pubout -out pub.pem
writing RSA key
$ echo &quot;hello rsa&quot; &gt; hello.txt
$ openssl rsautl -encrypt -pubin  -inkey pub.pem -in hello.txt -out hello.txt.crypto
$ openssl rsautl -decrypt -inkey priv.pem -in hello.txt.crypto
hello rsa
</pre>
<p>なんとなく流れは掴めた気がしますね。</p>
<p>さて鍵の生成はopensslコマンドでやれば良いとして、それを使って暗号化・復号をプログラムからやりたいですね。そこで次に上で作った秘密鍵・公開鍵をPythonから使ってみます。名前的には<a href="http://pypi.python.org/pypi/rsa" title="rsa module in pypi" target="_blank">rsaモジュール</a>を使いたいのですが、手元では色々と怪しい動きをしていたので、おとなしく<a href="http://pypi.python.org/pypi/pycrypto/2.5" title="PyCrypto in PyPI" target="_blank">PyCrypto</a>を使うのが良さそうです。</p>
<pre class="brush: python; gutter: true; first-line: 1; highlight: []; html-script: false">
import Crypto
from Crypto.PublicKey import RSA

pub = RSA.importKey(open(&#039;pub.pem&#039;, &#039;r&#039;).read())
priv = RSA.importKey(open(&#039;priv.pem&#039;, &#039;r&#039;).read())

text = open(&#039;hello.txt&#039;, &#039;r&#039;).read()
crypto = pub.encrypt(text, &#039;&#039;)
print priv.decrypt(crypto)

print &#039;PRIVATE KEY:\n  p=%s, \n  q=%s, \n  n=%s, \n  d=%s, \n  e=%s&#039; % (priv.p, priv.q, priv.n, priv.d, priv.e)
print &#039;PUBLIC KEY:\n  n=%s, \n  e=%s&#039; % (pub.n, pub.e)
</pre>
<p>これを実行すると以下のようになります。数が大きすぎて良く解らないですが、何となく正常に動いてる気がしますね。</p>
<pre class="brush: text; gutter: true; first-line: 1; highlight: []; html-script: false">
hello rsa world

PRIVATE KEY:
  p=312812244098101569570522771086507368199,
  q=261732496899955705693539027437044751693,
  n=81873129708674556552097159647951377728324724985548367405770094930146879610907,
  d=61350191904775909756579327908681267205274632675124298948670533913070326529385,
  e=65537
PUBLIC KEY:
  n=81873129708674556552097159647951377728324724985548367405770094930146879610907,
  e=65537
</pre>
<p>折角なので学習のため<a href="http://taichino.com/programming/2628" title="合同式の逆元を求める">先ほどのエントリ</a>で書いたmodinvを使って自分でも計算してみます。</p>
<pre class="brush: python; gutter: true; first-line: 1; highlight: []; html-script: false">
&gt;&gt; def calc(base, exp, modulus):
&gt;&gt;     ans = 1
&gt;&gt;     while exp &lt; 0:
&gt;&gt;         if exp &amp; 1:
&gt;&gt;             ans = (ans * base) % modulus
&gt;&gt;         exp &gt;&gt;= 1
&gt;&gt;         exp = int(exp)
&gt;&gt;         base = (base * base) % modulus
&gt;&gt;     return ans
&gt;&gt;
&gt;&gt; (p, q) = (65537, 55079)
&gt;&gt; m = p * q
&gt;&gt; phi = (p - 1) * (q - 1)
&gt;&gt; e = 65537
&gt;&gt; d = modinv(e, phi)
&gt;&gt; orig = 2900
&gt;&gt; encoded = calc(orig, e, m)
&gt;&gt; print encoded
60945415393350116455581236569596858319975698828166554225855598846369380497015
&gt;&gt; decoded = calc(encoded, d, m)
&gt;&gt; print decoded
2900
</pre>
<p>値が大きくなるのでベキ乗計算が少し面倒ですが、暗号化と復号ができました。まだ文字列をどうやって暗号化可能な数値に変換してるのかとか細かくは理解してないですけど何となくつかめた気がしてます。</p>
<p>さて最後にフォーマットについて確認します。opensslで生成した鍵(priv.pem, pub.pem)はPEM形式というやつで、中身はDER形式のデータをbase64でエンコードしたもののようです。例えば上で生成したファイルは下記のような姿をしています。</p>
<pre class="brush: text; gutter: true; first-line: 1; highlight: []; html-script: false">
-----BEGIN RSA PRIVATE KEY-----
MIGqAgEAAiEAtQKMmuoZNSc0jZe/TDf1p3bQraYwXvBkOdFSwJAkIBsCAwEAAQIh
AIei+mOXKf53e1ziqhleEXgAni7HKueUV/bWLRzb+D1pAhEA61VyYLHy31RSLJ3l
aWXfBwIRAMTn2GbiUscRRmBm9aiR3U0CEDnyEzS9/EiDUayMwHVAUTcCEBgXDWC4
+8ujD2sn7ZIsFlkCECAVBGiJ4VrYG6HTGgTflU4=
-----END RSA PRIVATE KEY-----
</pre>
<p>このファイルをDER形式に変換してみます。やはりopensslコマンドを使用します。</p>
<pre class="brush: bash; gutter: true; first-line: 1; highlight: []; html-script: false">
$ openssl rsa -inform PEM -outform DER -in priv.pem -out priv.der
</pre>
<p>変換後のDERファイルの内容をやはりopensslコマンドで読みます。この数値が大きい時に使われる表現をもとの数字に戻す方法が解らないのでどなたかご存知であれば教えてください。</p>
<pre class="brush: bash; gutter: true; first-line: 1; highlight: []; html-script: false">
$ openssl rsa -inform DER -in priv.der -text -noout
Private-Key: (256 bit)
modulus:
    00:b5:02:8c:9a:ea:19:35:27:34:8d:97:bf:4c:37:
    f5:a7:76:d0:ad:a6:30:5e:f0:64:39:d1:52:c0:90:
    24:20:1b
publicExponent: 65537 (0x10001)
privateExponent:
    00:87:a2:fa:63:97:29:fe:77:7b:5c:e2:aa:19:5e:
    11:78:00:9e:2e:c7:2a:e7:94:57:f6:d6:2d:1c:db:
    f8:3d:69
prime1:
    00:eb:55:72:60:b1:f2:df:54:52:2c:9d:e5:69:65:
    df:07
prime2:
    00:c4:e7:d8:66:e2:52:c7:11:46:60:66:f5:a8:91:
    dd:4d
exponent1:
    39:f2:13:34:bd:fc:48:83:51:ac:8c:c0:75:40:51:
    37
exponent2:
    18:17:0d:60:b8:fb:cb:a3:0f:6b:27:ed:92:2c:16:
    59
coefficient:
    20:15:04:68:89:e1:5a:d8:1b:a1:d3:1a:04:df:95:
    4e
</pre>
<p>全然細かい事は調べれてないのですが、何となくRSAの概要が把握できた気になっていて、コード追うくらいはできそうなのでこの辺にしておきます。</p>
]]></content:encoded>
			<wfw:commentRss>http://taichino.com/engineer-life/2647/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pythonで合同式の逆元を求める</title>
		<link>http://taichino.com/programming/2628</link>
		<comments>http://taichino.com/programming/2628#comments</comments>
		<pubDate>Wed, 01 Feb 2012 03:41:17 +0000</pubDate>
		<dc:creator>taichino</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[拡張ユークリッドの互除法]]></category>

		<guid isPermaLink="false">http://taichino.com/?p=2628</guid>
		<description><![CDATA[RSAをおさらいしていたら、合同式の逆元を求める必要がありました。合同式の逆元は拡張ユークリッドの互除法を使うと求められるのですが、逆元を求める際にどう拡張ユークリッドの互除法を使えば良いのか解らなくて、手間取ったのでメモしておきます。コードはPythonです。 一応解きたい式を書いておくと以下になります。 まず拡張ユークリッドの互除法をWikipedia通りに書きます。Wikipediaの擬似コードは何故かgcdの値を返してなかったのでgcdも返すように変更しました。 def egcd&#40;a, b&#41;: &#40;x, lastx&#41; = &#40;0, 1&#41; &#40;y, lasty&#41; = &#40;1, 0&#41; while b != 0: q = a // b &#40;a, b&#41; = &#40;b, a % b&#41; &#40;x, lastx&#41; = &#40;lastx - q * x, x&#41; &#40;y, lasty&#41; = &#40;lasty - q * y, y&#41; return &#40;lastx, lasty, a&#41; 次にこのegcdを使って合同式の逆元を求める訳ですが、どうにも解りやすい説明が見つからなくて困りました。色々見て回った結果、ここでもWikipediaの「Modular [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://ja.wikipedia.org/wiki/RSA%E6%9A%97%E5%8F%B7" title="RSA暗号" target="_blank">RSA</a>をおさらいしていたら、合同式の逆元を求める必要がありました。合同式の逆元は拡張ユークリッドの互除法を使うと求められるのですが、逆元を求める際にどう拡張ユークリッドの互除法を使えば良いのか解らなくて、手間取ったのでメモしておきます。コードはPythonです。</p>
<p>一応解きたい式を書いておくと以下になります。<br />
<img src='http://taichino.com/wp-content/plugins/wp-latexrender/pictures/8677d4cbaa413dabf10a16213a62cab6.gif' title='\mathfrak{a}x \equiv 1\ \pmod{\mathfrak{m}}' alt='\mathfrak{a}x \equiv 1\ \pmod{\mathfrak{m}}' align=absmiddle> </p>
<p><span id="more-2628"></span></p>
<p>まず拡張ユークリッドの互除法を<a href="http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm" title="拡張ユークリッドの互除法" target="_blank">Wikipedia通り</a>に書きます。Wikipediaの擬似コードは何故かgcdの値を返してなかったのでgcdも返すように変更しました。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> egcd<span style="color: black;">&#40;</span>a, b<span style="color: black;">&#41;</span>:
    <span style="color: black;">&#40;</span>x, lastx<span style="color: black;">&#41;</span> = <span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
    <span style="color: black;">&#40;</span>y, lasty<span style="color: black;">&#41;</span> = <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">while</span> b <span style="color: #66cc66;">!</span>= <span style="color: #ff4500;">0</span>:
        q = a // b
        <span style="color: black;">&#40;</span>a, b<span style="color: black;">&#41;</span> = <span style="color: black;">&#40;</span>b, a <span style="color: #66cc66;">%</span> b<span style="color: black;">&#41;</span>
        <span style="color: black;">&#40;</span>x, lastx<span style="color: black;">&#41;</span> = <span style="color: black;">&#40;</span>lastx - q <span style="color: #66cc66;">*</span> x, x<span style="color: black;">&#41;</span>
        <span style="color: black;">&#40;</span>y, lasty<span style="color: black;">&#41;</span> = <span style="color: black;">&#40;</span>lasty - q <span style="color: #66cc66;">*</span> y, y<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span>lastx, lasty, a<span style="color: black;">&#41;</span></pre></div></div>

<p>次にこのegcdを使って合同式の逆元を求める訳ですが、どうにも解りやすい説明が見つからなくて困りました。色々見て回った結果、ここでもWikipediaの「<a href="http://en.wikipedia.org/wiki/Modular_multiplicative_inverse" title="合同式の逆元" target="_blank">Modular multiplicative inverse</a>」が一番解りやすかったです。ページに書かれている通りegcdを使って逆元を求めます。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># ax ≡ 1 (mod m)</span>
<span style="color: #ff7700;font-weight:bold;">def</span> modinv<span style="color: black;">&#40;</span>a, m<span style="color: black;">&#41;</span>:
    <span style="color: black;">&#40;</span>inv, q, gcd_val<span style="color: black;">&#41;</span> = egcd<span style="color: black;">&#40;</span>a, m<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> inv <span style="color: #66cc66;">%</span> m</pre></div></div>

<p>上記のmodinvで冒頭の式中のxを求められました。結果だけ見るとなんでもないですね。アルゴリズムが苦手なのでもっと精進します。</p>
<p>アルゴリズム系はWikipediaが便利すぎますね。そしてPythonはWikipediaに張られている擬似コードがほぼ機械的な修正のみで動くので素晴らしいです。</p>
]]></content:encoded>
			<wfw:commentRss>http://taichino.com/programming/2628/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>django.utils.functionalを読んだメモ</title>
		<link>http://taichino.com/programming/2507</link>
		<comments>http://taichino.com/programming/2507#comments</comments>
		<pubDate>Wed, 21 Dec 2011 14:28:44 +0000</pubDate>
		<dc:creator>taichino</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[django.utils.functional]]></category>

		<guid isPermaLink="false">http://taichino.com/?p=2507</guid>
		<description><![CDATA[django関連のコードを読んでいて、django.utils.functionalというモジュールが目につきました。中を見るとカリー化や遅延評価など聞いたは事あるものの、いまいちピンとこなかったので、調べた事のメモ書きを残しておきます。 まずはカリー化を行うcurryという関数。 #!/usr/bin/python # -*- coding: utf-8 -*- &#160; from django.utils.functional import curry &#160; def orig&#40;a, b&#41;: print &#34;a=%(a)s, b=%(b)s&#34; % locals&#40;&#41; &#160; def orig2&#40;a, b, c&#41;: print &#34;a=%(a)s, b=%(b)s c=%(c)s&#34; % locals&#40;&#41; &#160; curried = curry&#40;orig, a=&#34;before&#34;&#41; curried&#40;b=&#34;try1&#34;&#41; curried&#40;b=&#34;try2&#34;&#41; &#160; curried2 = curry&#40;orig2, a=&#34;val_a&#34;&#41; curried2&#40;b=&#34;after_b&#34;, c=&#34;after_c&#34;&#41; wikipediaによるとカリー化は複数引数を持つ関数を、単一引数の関数の組み合わせとして表現することとあるので、多分この関数と上記の使い方は、実際はカリー化じゃなくて引数の部分適用というのが正しそうです。まぁ引数が複数あって、それぞれ評価したいタイミングが異なるというのは良くありますね。もっと早く知りたかった。 後この関数の実装が綺麗で、あぁなるほど！と思いましたので引用します。今上手く言語化できないですが、スコープを上手く制御していますね。 def curry&#40;_curried_func, *args, **kwargs&#41;: def _curried&#40;*moreargs, [...]]]></description>
			<content:encoded><![CDATA[<p>django関連のコードを読んでいて、django.utils.functionalというモジュールが目につきました。中を見るとカリー化や遅延評価など聞いたは事あるものの、いまいちピンとこなかったので、調べた事のメモ書きを残しておきます。</p>
<p><span id="more-2507"></span></p>
<p>まずはカリー化を行うcurryという関数。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span>.<span style="color: black;">functional</span> <span style="color: #ff7700;font-weight:bold;">import</span> curry
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> orig<span style="color: black;">&#40;</span>a, b<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;a=%(a)s, b=%(b)s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: #008000;">locals</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> orig2<span style="color: black;">&#40;</span>a, b, c<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;a=%(a)s, b=%(b)s c=%(c)s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: #008000;">locals</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
curried = curry<span style="color: black;">&#40;</span>orig, a=<span style="color: #483d8b;">&quot;before&quot;</span><span style="color: black;">&#41;</span>
curried<span style="color: black;">&#40;</span>b=<span style="color: #483d8b;">&quot;try1&quot;</span><span style="color: black;">&#41;</span>
curried<span style="color: black;">&#40;</span>b=<span style="color: #483d8b;">&quot;try2&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
curried2 = curry<span style="color: black;">&#40;</span>orig2, a=<span style="color: #483d8b;">&quot;val_a&quot;</span><span style="color: black;">&#41;</span>
curried2<span style="color: black;">&#40;</span>b=<span style="color: #483d8b;">&quot;after_b&quot;</span>, c=<span style="color: #483d8b;">&quot;after_c&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p><a href="http://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%AA%E3%83%BC%E5%8C%96">wikipediaによると</a>カリー化は複数引数を持つ関数を、単一引数の関数の組み合わせとして表現することとあるので、多分この関数と上記の使い方は、実際はカリー化じゃなくて引数の部分適用というのが正しそうです。まぁ引数が複数あって、それぞれ評価したいタイミングが異なるというのは良くありますね。もっと早く知りたかった。</p>
<p>後この関数の実装が綺麗で、あぁなるほど！と思いましたので引用します。今上手く言語化できないですが、スコープを上手く制御していますね。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> curry<span style="color: black;">&#40;</span>_curried_func, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> _curried<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>moreargs, <span style="color: #66cc66;">**</span>morekwargs<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> _curried_func<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: black;">&#40;</span>args+moreargs<span style="color: black;">&#41;</span>, <span style="color: #66cc66;">**</span><span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>kwargs, <span style="color: #66cc66;">**</span>morekwargs<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> _curried</pre></div></div>

<p>次にSimpleLazyObject。オブジェクトの初期化を実際にオブジェクトを利用するタイミングまで遅らせられます。プロパティアクセスする時に初めて初期化されるみたいなノリです。特定のオブジェクトのファクトリ関数をSimpleLazyObjectに渡して利用します。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span>.<span style="color: black;">functional</span> <span style="color: #ff7700;font-weight:bold;">import</span> SimpleLazyObject
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> TargetObject<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;__init__&quot;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">name</span> = name
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__eq__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, other<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">name</span> == other.<span style="color: black;">name</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__hash__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">hash</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">name</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__str__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;I am %s(%r)&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.__class__, <span style="color: #008000;">self</span>.<span style="color: black;">name</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__unicode__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">name</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__repr__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;%s(%r)&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.__class__, <span style="color: #008000;">self</span>.<span style="color: black;">name</span><span style="color: black;">&#41;</span>
&nbsp;
create_target = <span style="color: #ff7700;font-weight:bold;">lambda</span>: TargetObject<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;target1&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;before init lazy_obj&quot;</span>
lazy_obj = SimpleLazyObject<span style="color: black;">&#40;</span>create_target<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;after init lazy_obj&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;before access prop of lazy_obj&quot;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> lazy_obj.<span style="color: black;">name</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;after access prop of lazy_obj&quot;</span></pre></div></div>

<p>先ほどのcurryと組み合わせて、オブジェクトのファクトリ関数をcurryでラップすると便利な気がします。djangoでいうとmiddlewareとかにとりあえず入れとくと便利やけど、毎度呼ばれると重いような処理を軽減できそうです。</p>
<p>次はlazy。関数の実際の呼び出しを遅延させられる関数で、<a href="http://d.hatena.ne.jp/perezvon/20061022/1161530146">コチラの解説</a>が分かりやすかったです。今のところ便利そうというのは分かりますが、具体的な利用シーンは思いついてないです。まぁ関数がファーストオブジェクトって言うのを活かそうとすると自然と使いそうではあります。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span>.<span style="color: black;">functional</span> <span style="color: #ff7700;font-weight:bold;">import</span> lazy
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> get_value_with_sometime<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'get_value_with_sometime!'</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'real val'</span>
&nbsp;
lazy_get_value = lazy<span style="color: black;">&#40;</span>get_value_with_sometime, <span style="color: #008000;">str</span><span style="color: black;">&#41;</span>
&nbsp;
d = <span style="color: black;">&#123;</span> <span style="color: #483d8b;">'exist_key'</span>:<span style="color: #483d8b;">'some val'</span> <span style="color: black;">&#125;</span>
value = d.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'exist_key'</span>, lazy_get_value<span style="color: black;">&#40;</span><span style="color: #483d8b;">'exist_key'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> value</pre></div></div>

<p>他にもデコレータのmemoizeとかallow_lazyとかが定義されていて、もっと早く読んどけば良かったなと思った次第です。あと関数型の考え方をちゃんと身につけたくなってきました。</p>
]]></content:encoded>
			<wfw:commentRss>http://taichino.com/programming/2507/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DjangoでJinja2を使いたいという話</title>
		<link>http://taichino.com/programming/2255</link>
		<comments>http://taichino.com/programming/2255#comments</comments>
		<pubDate>Wed, 12 Oct 2011 16:31:48 +0000</pubDate>
		<dc:creator>taichino</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[jinja2]]></category>

		<guid isPermaLink="false">http://taichino.com/?p=2255</guid>
		<description><![CDATA[先ほどの記事にも書いたようにAppStatsは、Kay frameworkで途中まで書いたコードをDjangoに移植したんですが、その際にテンプレートエンジンの差異に少し戸惑いました。 Kayで採用されているjinja2はDjangoの標準テンプレートに良く似せて作られていて、Djangoを触った事があれば違和感無く使い始められます。ところがDjangoでイマイチな部分が解消されていて、一度jinja2を使ってしまうとDjangoに戻ってきた時にイライラしてしまうという問題が生じます。jinja2の何が良いかというと、例えばdjangoのドット記法はヤダとか、テンプレート中で関数呼び出しを見慣れている形で記述できるとか、デフォで{% macro %}が使える等などです。 正直macroなんかは一回使ったらもう同等機能がないテンプレートシステムなんて使えないです。という訳でDjangoでもjinja2を使いたいということで、調べた方法を記録しておきます。 ありがたい事にDjangoにはテンプレートのローダーをプラガブルに設定する仕組みが備わっています。なので下記のようなシンプルな手順でjinja2を使えるようになりました。 jinja2用のテンプレートローダを記述 &#8211; jinja2にKayのurl_forにあたるURL逆引き関数を設定 &#8211; jinja2にi18nの設定を行う settings.pyに1のローダを指定 1. jinja2用のローダを記述 ローダはgistに張られていたコチラのコードをほぼ丸パクリさせてもらいました。修正したポイントは上記の2点です。まず今回Kayからの移植という事もあり、URLの逆引き関数が必要だったので、django.core.urlresolvers.reverseをテンプレート中で使えるようにしています。関数名はKayに合わせてurl_forました。もう一点はi18nの設定です。jinja2には国際化を行う為のクラスを指定する仕組みが備わっているので、そこにDjangoの翻訳モジュールを指定します。こうするとDjangoで作成できる.poファイルをjinja2からそのまま利用できます。 あと補足ですが、このローダは拡張子が.htmlのものをロードしません。なのでDjango標準のテンプレートとjinja2のテンプレートを共存させられます。 from django.core.urlresolvers import get_callable from django.template import TemplateDoesNotExist from django.template.loader import BaseLoader from django.template.context import BaseContext from django.conf import settings from django.utils import translation from django.core import urlresolvers &#160; import jinja2 &#160; def monkey_patch_django&#40;&#41;: &#34;&#34;&#34; Patching some django [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://taichino.com/programming/2231">先ほどの記事</a>にも書いたように<a href="http://ios.app-stats.info/ja/pc">AppStats</a>は、<a href="http://code.google.com/p/kay-framework/">Kay framework</a>で途中まで書いたコードをDjangoに移植したんですが、その際にテンプレートエンジンの差異に少し戸惑いました。</p>
<p>Kayで採用されている<a href="http://jinja.pocoo.org/docs/">jinja2</a>はDjangoの標準テンプレートに良く似せて作られていて、Djangoを触った事があれば違和感無く使い始められます。ところがDjangoでイマイチな部分が解消されていて、一度jinja2を使ってしまうとDjangoに戻ってきた時にイライラしてしまうという問題が生じます。jinja2の何が良いかというと、例えばdjangoのドット記法はヤダとか、テンプレート中で関数呼び出しを見慣れている形で記述できるとか、デフォで{% macro %}が使える等などです。</p>
<p>正直macroなんかは一回使ったらもう同等機能がないテンプレートシステムなんて使えないです。という訳でDjangoでもjinja2を使いたいということで、調べた方法を記録しておきます。</p>
<p><span id="more-2255"></span></p>
<p>ありがたい事にDjangoにはテンプレートのローダーをプラガブルに設定する仕組みが備わっています。なので下記のようなシンプルな手順でjinja2を使えるようになりました。</p>
<ol>
<li> jinja2用のテンプレートローダを記述<br />
   &#8211; jinja2にKayのurl_forにあたるURL逆引き関数を設定<br />
   &#8211; jinja2にi18nの設定を行う
</li>
<li>settings.pyに1のローダを指定</li>
</ol>
<p><strong>1. jinja2用のローダを記述</strong><br />
ローダはgistに張られていた<a href="http://djangosnippets.org/snippets/363/">コチラのコード</a>をほぼ丸パクリさせてもらいました。修正したポイントは上記の2点です。まず今回Kayからの移植という事もあり、URLの逆引き関数が必要だったので、django.core.urlresolvers.reverseをテンプレート中で使えるようにしています。関数名はKayに合わせてurl_forました。もう一点はi18nの設定です。jinja2には国際化を行う為のクラスを指定する仕組みが備わっているので、そこにDjangoの翻訳モジュールを指定します。こうするとDjangoで作成できる.poファイルをjinja2からそのまま利用できます。</p>
<p>あと補足ですが、このローダは拡張子が.htmlのものをロードしません。なのでDjango標準のテンプレートとjinja2のテンプレートを共存させられます。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">core</span>.<span style="color: black;">urlresolvers</span> <span style="color: #ff7700;font-weight:bold;">import</span> get_callable
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">template</span> <span style="color: #ff7700;font-weight:bold;">import</span> TemplateDoesNotExist
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">template</span>.<span style="color: black;">loader</span> <span style="color: #ff7700;font-weight:bold;">import</span> BaseLoader
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">template</span>.<span style="color: black;">context</span> <span style="color: #ff7700;font-weight:bold;">import</span> BaseContext
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span> <span style="color: #ff7700;font-weight:bold;">import</span> settings
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span> <span style="color: #ff7700;font-weight:bold;">import</span> translation
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">core</span> <span style="color: #ff7700;font-weight:bold;">import</span> urlresolvers
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> jinja2
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> monkey_patch_django<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    Patching some django objects to make them &quot;safe&quot; for jinja's escape() function.
    Good for us it uses __html__() method.
    &quot;&quot;&quot;</span>
    <span style="color: #808080; font-style: italic;"># Django's SafeString and SafeUnicode should not be escaped:</span>
    <span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span>.<span style="color: black;">safestring</span> <span style="color: #ff7700;font-weight:bold;">import</span> SafeData
    SafeData.__html__ = <span style="color: #ff7700;font-weight:bold;">lambda</span> <span style="color: #008000;">self</span>: <span style="color: #008000;">self</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">from</span> jinja2 <span style="color: #ff7700;font-weight:bold;">import</span> escape
    <span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">forms</span> <span style="color: #ff7700;font-weight:bold;">import</span> BaseForm, Media
    <span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">forms</span>.<span style="color: black;">forms</span> <span style="color: #ff7700;font-weight:bold;">import</span> BoundField
    <span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">forms</span>.<span style="color: black;">formsets</span> <span style="color: #ff7700;font-weight:bold;">import</span> BaseFormSet
    <span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">forms</span>.<span style="color: black;">util</span> <span style="color: #ff7700;font-weight:bold;">import</span> ErrorDict, ErrorList
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> cls <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#40;</span>BaseForm, Media, BoundField, BaseFormSet, ErrorDict, ErrorList<span style="color: black;">&#41;</span>:
        cls.__html__ = <span style="color: #ff7700;font-weight:bold;">lambda</span> <span style="color: #008000;">self</span>: escape<span style="color: black;">&#40;</span><span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Template<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    A container for jinja2 Template class
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, template, origin=<span style="color: #008000;">None</span>, name=<span style="color: #483d8b;">'&lt;unknown Template&gt;'</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">template</span> = template
        <span style="color: #008000;">self</span>.<span style="color: black;">origin</span> = origin
        <span style="color: #008000;">self</span>.<span style="color: black;">name</span> = name
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> render<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, context<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>context, BaseContext<span style="color: black;">&#41;</span>:
            d = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
            <span style="color: #ff7700;font-weight:bold;">for</span> u <span style="color: #ff7700;font-weight:bold;">in</span> context.<span style="color: black;">dicts</span>:
                d.<span style="color: black;">update</span><span style="color: black;">&#40;</span>u<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            d = context
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">template</span>.<span style="color: black;">render</span><span style="color: black;">&#40;</span>d<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Loader<span style="color: black;">&#40;</span>BaseLoader<span style="color: black;">&#41;</span>:
    is_usable = <span style="color: #008000;">True</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;
        Creating jinja2 environment
        &quot;&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #008000;">hasattr</span><span style="color: black;">&#40;</span>settings, <span style="color: #483d8b;">'TEMPLATE_DIRS'</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'Jinja2 template loader needs TEMPLATE_DIRS setting'</span>
        monkey_patch_django<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        extras = <span style="color: #008000;">self</span>._get_env_extras<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        options = <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>settings, <span style="color: #483d8b;">'JINJA2_ENVIRONMENT_OPTIONS'</span>, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
        options<span style="color: black;">&#91;</span><span style="color: #483d8b;">'extensions'</span><span style="color: black;">&#93;</span> = extras<span style="color: black;">&#91;</span><span style="color: #483d8b;">'extensions'</span><span style="color: black;">&#93;</span>
        options<span style="color: black;">&#91;</span><span style="color: #483d8b;">'loader'</span><span style="color: black;">&#93;</span> = jinja2.<span style="color: black;">FileSystemLoader</span><span style="color: black;">&#40;</span>settings.<span style="color: black;">TEMPLATE_DIRS</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">### Some special tuning of jinja2 environment goes here</span>
        <span style="color: #808080; font-style: italic;"># Number of compiled jinja2 templates in process memory</span>
        options<span style="color: black;">&#91;</span><span style="color: #483d8b;">'cache_size'</span><span style="color: black;">&#93;</span> = -<span style="color: #ff4500;">1</span>
        <span style="color: #808080; font-style: italic;"># Check whether template file is changed only in development</span>
        options<span style="color: black;">&#91;</span><span style="color: #483d8b;">'auto_reload'</span><span style="color: black;">&#93;</span> = settings.<span style="color: black;">DEBUG</span>
        <span style="color: #808080; font-style: italic;"># Use jinja's bytecode cache</span>
        options<span style="color: black;">&#91;</span><span style="color: #483d8b;">'bytecode_cache'</span><span style="color: black;">&#93;</span> = jinja2.<span style="color: black;">FileSystemBytecodeCache</span><span style="color: black;">&#40;</span>settings.<span style="color: black;">BASE_DIR</span> + <span style="color: #483d8b;">'/tmp/jinja_cache'</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">env</span> = jinja2.<span style="color: black;">Environment</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">**</span>options<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: black;">filters</span>.<span style="color: black;">update</span><span style="color: black;">&#40;</span>extras<span style="color: black;">&#91;</span><span style="color: #483d8b;">'filters'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: #008000;">globals</span>.<span style="color: black;">update</span><span style="color: black;">&#40;</span>extras<span style="color: black;">&#91;</span><span style="color: #483d8b;">'globals'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: black;">tests</span>.<span style="color: black;">update</span><span style="color: black;">&#40;</span>extras<span style="color: black;">&#91;</span><span style="color: #483d8b;">'tests'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># 1. urlresolvers.reverseをurl_forとして登録</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: #008000;">globals</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'url_for'</span><span style="color: black;">&#93;</span> = urlresolvers.<span style="color: black;">reverse</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># 2. djangoの翻訳モジュールをjinjaに登録</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">'jinja2.ext.i18n'</span> <span style="color: #ff7700;font-weight:bold;">in</span> options<span style="color: black;">&#91;</span><span style="color: #483d8b;">'extensions'</span><span style="color: black;">&#93;</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: black;">install_gettext_translations</span><span style="color: black;">&#40;</span>translation<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _get_env_extras<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;
        Creates a dict of extensions, filters, globals and tests from settings
        &quot;&quot;&quot;</span>
        extensions, filters, objects, tests = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># add the globally defined extension list</span>
        extensions.<span style="color: black;">extend</span><span style="color: black;">&#40;</span><span style="color: #008000;">list</span><span style="color: black;">&#40;</span><span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>settings, <span style="color: #483d8b;">'JINJA2_EXTENSIONS'</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># parse filters, globals and tests settings</span>
        <span style="color: #ff7700;font-weight:bold;">def</span> from_setting<span style="color: black;">&#40;</span>setting<span style="color: black;">&#41;</span>:
            retval = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
            setting = <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>settings, setting, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>setting, <span style="color: #008000;">dict</span><span style="color: black;">&#41;</span>:
                <span style="color: #ff7700;font-weight:bold;">for</span> key, value <span style="color: #ff7700;font-weight:bold;">in</span> setting.<span style="color: black;">iteritems</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
                    retval<span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span> = <span style="color: #008000;">callable</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> value <span style="color: #ff7700;font-weight:bold;">or</span> get_callable<span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #ff7700;font-weight:bold;">for</span> value <span style="color: #ff7700;font-weight:bold;">in</span> setting:
                    value = <span style="color: #008000;">callable</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> value <span style="color: #ff7700;font-weight:bold;">or</span> get_callable<span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span>
                    retval<span style="color: black;">&#91;</span>value.__name__<span style="color: black;">&#93;</span> = value
            <span style="color: #ff7700;font-weight:bold;">return</span> retval
&nbsp;
        filters.<span style="color: black;">update</span><span style="color: black;">&#40;</span>from_setting<span style="color: black;">&#40;</span><span style="color: #483d8b;">'JINJA2_FILTERS'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        objects.<span style="color: black;">update</span><span style="color: black;">&#40;</span>from_setting<span style="color: black;">&#40;</span><span style="color: #483d8b;">'JINJA2_GLOBALS'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        tests.<span style="color: black;">update</span><span style="color: black;">&#40;</span>from_setting<span style="color: black;">&#40;</span><span style="color: #483d8b;">'JINJA2_TESTS'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>
            extensions=extensions,
            filters=filters,
            <span style="color: #008000;">globals</span>=objects,
            tests=tests,
        <span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> load_template<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, template_name, template_dirs=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># Leave .html extension for django template (admin, contrib, etc)</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> template_name.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.html'</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateDoesNotExist<span style="color: black;">&#40;</span>template_name<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            template = <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: black;">get_template</span><span style="color: black;">&#40;</span>template_name<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> Template<span style="color: black;">&#40;</span>template, <span style="color: #008000;">None</span>, template_name<span style="color: black;">&#41;</span>, <span style="color: #008000;">None</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> jinja2.<span style="color: black;">TemplateNotFound</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateDoesNotExist<span style="color: black;">&#40;</span>template_name<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> load_template_source<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, template_name, template_dirs=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># Leave .html extension for django template (admin, contrib, etc)</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> template_name.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.html'</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateDoesNotExist<span style="color: black;">&#40;</span>template_name<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            source, filename, uptodate = <span style="color: #008000;">self</span>.<span style="color: black;">env</span>.<span style="color: black;">loader</span>.<span style="color: black;">get_source</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">env</span>, template_name<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> source, filename
        <span style="color: #ff7700;font-weight:bold;">except</span> jinja2.<span style="color: black;">TemplateNotFound</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateDoesNotExist<span style="color: black;">&#40;</span>template_name<span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&lt;</span>/unknown<span style="color: #66cc66;">&gt;</span></pre></div></div>

<p><strong>2. settings.pyに1のローダを指定</strong><br />
次に1で作ったローダをsettings.pyに記述しましょう。同時にJINJA2_EXTENSIONSも記述します。<br />
また自分のフィルタを追加する場合はJINJA2_FILTERSに追記すればOKです。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">TEMPLATE_LOADERS = <span style="color: black;">&#40;</span>
  <span style="color: #483d8b;">'jinjalink_loader.Loader'</span>,
  <span style="color: #483d8b;">'django.template.loaders.filesystem.Loader'</span>,
  <span style="color: #483d8b;">'django.template.loaders.app_directories.Loader'</span>,
<span style="color: black;">&#41;</span>
&nbsp;
JINJA2_EXTENSIONS = <span style="color: black;">&#40;</span>
  <span style="color: #483d8b;">'jinja2.ext.with_'</span>,
  <span style="color: #483d8b;">'jinja2.ext.i18n'</span>,
<span style="color: black;">&#41;</span>
JINJA2_FILTERS = <span style="color: black;">&#123;</span>
  ...
<span style="color: black;">&#125;</span>
JINJA2_ENVIRONMENT_OPTIONS = <span style="color: black;">&#123;</span>
  ...
<span style="color: black;">&#125;</span></pre></div></div>

<p>以上でjinja2をDjangoから使えるようになりました。jinja2は本当に便利で、Django使うのがさらに楽しくなるのでオススメです。あとどうでも良いんですが、jinja2のテンプレートの拡張子って皆さん何使ってるんでしょうか。僕はもっぱら.j2なんですけど。</p>
]]></content:encoded>
			<wfw:commentRss>http://taichino.com/programming/2255/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

