1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.fontbox.cff;
18
19 /**
20 * This class contains some helper methods handling Type1-Fonts.
21 *
22 * @author Villu Ruusmann
23 * @version $Revision$
24 */
25 public class Type1FontUtil
26 {
27
28 private Type1FontUtil()
29 {
30 }
31
32 /**
33 * Converts a byte-array into a string with the corresponding hex value.
34 * @param bytes the byte array
35 * @return the string with the hex value
36 */
37 public static String hexEncode(byte[] bytes)
38 {
39 StringBuilder sb = new StringBuilder();
40 for (int i = 0; i < bytes.length; i++)
41 {
42 String string = Integer.toHexString(bytes[i] & 0xff);
43 if (string.length() == 1)
44 {
45 sb.append("0");
46 }
47 sb.append(string.toUpperCase());
48 }
49 return sb.toString();
50 }
51
52 /**
53 * Converts a string representing a hex value into a byte array.
54 * @param string the string representing the hex value
55 * @return the hex value as byte array
56 */
57 public static byte[] hexDecode(String string)
58 {
59 if (string.length() % 2 != 0)
60 {
61 throw new IllegalArgumentException();
62 }
63 byte[] bytes = new byte[string.length() / 2];
64 for (int i = 0; i < string.length(); i += 2)
65 {
66 bytes[i / 2] = (byte) Integer.parseInt(string.substring(i, i + 2), 16);
67 }
68 return bytes;
69 }
70
71 /**
72 * Encrypt eexec.
73 * @param buffer the given data
74 * @return the encrypted data
75 */
76 public static byte[] eexecEncrypt(byte[] buffer)
77 {
78 return encrypt(buffer, 55665, 4);
79 }
80
81 /**
82 * Encrypt charstring.
83 * @param buffer the given data
84 * @param n blocksize?
85 * @return the encrypted data
86 */
87 public static byte[] charstringEncrypt(byte[] buffer, int n)
88 {
89 return encrypt(buffer, 4330, n);
90 }
91
92 private static byte[] encrypt(byte[] plaintextBytes, int r, int n)
93 {
94 byte[] buffer = new byte[plaintextBytes.length + n];
95
96 for (int i = 0; i < n; i++)
97 {
98 buffer[i] = 0;
99 }
100
101 System.arraycopy(plaintextBytes, 0, buffer, n, buffer.length - n);
102
103 int c1 = 52845;
104 int c2 = 22719;
105
106 byte[] ciphertextBytes = new byte[buffer.length];
107
108 for (int i = 0; i < buffer.length; i++)
109 {
110 int plain = buffer[i] & 0xff;
111 int cipher = plain ^ r >> 8;
112
113 ciphertextBytes[i] = (byte) cipher;
114
115 r = (cipher + r) * c1 + c2 & 0xffff;
116 }
117
118 return ciphertextBytes;
119 }
120
121 /**
122 * Decrypt eexec.
123 * @param buffer the given encrypted data
124 * @return the decrypted data
125 */
126 public static byte[] eexecDecrypt(byte[] buffer)
127 {
128 return decrypt(buffer, 55665, 4);
129 }
130
131 /**
132 * Decrypt charstring.
133 * @param buffer the given encrypted data
134 * @param n blocksize?
135 * @return the decrypted data
136 */
137 public static byte[] charstringDecrypt(byte[] buffer, int n)
138 {
139 return decrypt(buffer, 4330, n);
140 }
141
142 private static byte[] decrypt(byte[] ciphertextBytes, int r, int n)
143 {
144 byte[] buffer = new byte[ciphertextBytes.length];
145
146 int c1 = 52845;
147 int c2 = 22719;
148
149 for (int i = 0; i < ciphertextBytes.length; i++)
150 {
151 int cipher = ciphertextBytes[i] & 0xff;
152 int plain = cipher ^ r >> 8;
153
154 buffer[i] = (byte) plain;
155
156 r = (cipher + r) * c1 + c2 & 0xffff;
157 }
158
159 byte[] plaintextBytes = new byte[ciphertextBytes.length - n];
160 System.arraycopy(buffer, n, plaintextBytes, 0, plaintextBytes.length);
161
162 return plaintextBytes;
163 }
164 }