aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2015-12-28 02:46:50 +0100
committerLars Ingebrigtsen2015-12-28 02:46:50 +0100
commit6a15c60d348c2652cca15b723ff72f8a6c53bb08 (patch)
tree26fa1624d0119923ae430d7349503900160deb6b
parent1fe73447864345c03fb28005122137419286853b (diff)
downloademacs-6a15c60d348c2652cca15b723ff72f8a6c53bb08.tar.gz
emacs-6a15c60d348c2652cca15b723ff72f8a6c53bb08.zip
Added basic idna encoding support
* lisp/net/idna.el: New file.
-rw-r--r--lisp/net/idna.el127
1 files changed, 127 insertions, 0 deletions
diff --git a/lisp/net/idna.el b/lisp/net/idna.el
new file mode 100644
index 00000000000..24a771b0bb8
--- /dev/null
+++ b/lisp/net/idna.el
@@ -0,0 +1,127 @@
1;;; idna.el --- translate non-ASCII domain names to ASCII
2
3;; Copyright (C) 2015 Free Software Foundation, Inc.
4
5;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
6;; Keywords: mail, net
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software: you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
22
23;;; Commentary:
24
25;; Written by looking at
26;; http://stackoverflow.com/questions/183485/can-anyone-recommend-a-good-free-javascript-for-punycode-to-unicode-conversion
27
28;;; Code:
29
30(defun idna-encode-string (string)
31 (cl-destructuring-bind (ascii complex)
32 (cl-loop for i from 0
33 for char across string
34 when (< char 128)
35 collect char into ascii
36 else
37 collect (cons i char) into complex
38 finally (return (list ascii complex)))
39 (concat (mapconcat 'string ascii "")
40 "-"
41 (idna-encode-complex (length ascii)
42 (sort complex
43 (lambda (e1 e2)
44 (< (cdr e1) (cdr e2))))
45 string))))
46
47(defconst idna-initial-n 128)
48(defconst idna-initial-bias 72)
49(defconst idna-base 36)
50(defconst idna-damp 700)
51(defconst idna-tmin 1)
52(defconst idna-tmax 26)
53(defconst idna-skew 28)
54
55(defun idna-decode-digit (cp)
56 (if (< (- cp 48) 10)
57 (- cp 22)
58 (if (< (- cp 65) 26)
59 (- cp 65)
60 (if (< (- cp 97) 26)
61 (- cp 97)
62 idna-base))))
63
64;; 0-25 a-z
65;; 26-36 0-9
66(defun idna-encode-digit (d)
67 (if (< d 26)
68 (+ ?a d)
69 (+ ?0 (- d 26))))
70
71(defun idna-adapt (delta num-points first-time)
72 (let ((delta (if first-time
73 (/ delta idna-damp)
74 (/ delta 2)))
75 (k 0))
76 (setq delta (+ delta (/ delta num-points)))
77 (cl-loop while (> delta (/ (* (- idna-base idna-tmin)
78 idna-tmax)
79 2))
80 do (setq delta (/ delta (- idna-base idna-tmin))
81 k (+ k idna-base)))
82 (+ k (/ (* (1+ (- idna-base idna-tmin)) delta)
83 (+ delta idna-skew)))))
84
85(defun idna-encode-complex (insertion-points complex string)
86 (let ((n idna-initial-n)
87 (delta 0)
88 (bias idna-initial-bias)
89 (h insertion-points)
90 result m)
91 (while (< h (length string))
92 (setq ijv (cl-loop for char across string
93 when (>= char n)
94 minimize char))
95 (setq m ijv)
96 (setq delta (+ delta (* (- m n) (+ h 1)))
97 n m)
98 (cl-loop for char across string
99 when (< char n)
100 do (cl-incf delta)
101 when (= char ijv)
102 do (progn
103 (setq q delta)
104 (cl-loop with k = idna-base
105 for t1 = (if (<= k bias)
106 idna-tmin
107 (if (>= k (+ bias idna-tmax))
108 idna-tmax
109 (- k bias)))
110 while (>= q t1)
111 do (push (idna-encode-digit
112 (+ t1 (mod (- q t1)
113 (- idna-base t1))))
114 result)
115 do (setq q (/ (- q t1) (- idna-base t1))
116 k (+ k idna-base)))
117 (push (idna-encode-digit q) result)
118 (setq bias (idna-adapt delta (+ h 1) (= h insertion-points))
119 delta 0
120 h (1+ h))))
121 (cl-incf delta)
122 (cl-incf n))
123 (nreverse result)))
124
125(provide 'idna)
126
127;;; shr.el ends here