View Javadoc

1   /*
2    * Copyright 2006 Christian Kalkhoff <me@ninan.info>
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package net.sf.plausj.bank.german.strategy;
18  
19  import net.sf.plausj.bank.german.AccountCode;
20  import net.sf.plausj.bank.german.BankCode;
21  import net.sf.plausj.bank.german.CheckDigit;
22  
23  /**
24   * @author ninan
25   * 
26   */
27  public class Strategy87 implements Strategy {
28  
29  	private static final int[] tabOneMethodA = new int[] { 0, 4, 3, 2, 6 };
30  
31  	private static final int[] tabTwoMethodA = new int[] { 7, 1, 5, 9, 8 };
32  
33  	private static final int[] multiplicatorsMethodC = new int[] { 0, 0, 0, 0,
34  			6, 5, 4, 3, 2 };
35  
36  	/**
37  	 * @see net.sf.plausj.bank.german.strategy.Strategy#calculateCheckDigit(net.sf.plausj.bank.german.BankCode,
38  	 *      net.sf.plausj.bank.german.AccountCode)
39  	 */
40  	public CheckDigit calculateCheckDigit(final BankCode bankCode,
41  			final AccountCode accountCode) {
42  
43  		CheckDigit cd = calculateMethodA(accountCode);
44  		if (!accountCode.matchesCheckDigit(cd)) {
45  			cd = calculateMethodB(accountCode);
46  			if (!accountCode.matchesCheckDigit(cd)) {
47  				cd = calculateMethodC(accountCode);
48  			}
49  		}
50  		return cd;
51  	}
52  
53  	private CheckDigit calculateMethodA(final AccountCode accountCode) {
54  
55  		int cd = 0;
56  
57  		int[] account = accountCode.getAsIntArray();
58  
59  		int i = 3;
60  		while (accountCode.getDigitAtPos(i) == 0) {
61  			++i;
62  		}
63  
64  		int c2 = (i + 1) % 2;
65  		int d2 = 0;
66  		int a5 = 0;
67  		while (i < 9) {
68  			switch (account[i]) {
69  			case 0:
70  				account[i] = 5;
71  				break;
72  			case 1:
73  				account[i] = 6;
74  				break;
75  			case 5:
76  				account[i] = 10;
77  				break;
78  			case 6:
79  				account[i] = 1;
80  				break;
81  			}
82  			if (c2 == d2) {
83  				if (account[i] > 5) {
84  					if (c2 == 0 && d2 == 0) {
85  						c2 = 1;
86  						d2 = 1;
87  						a5 = a5 + 6 - (account[i] - 6);
88  					} else {
89  						c2 = 0;
90  						d2 = 0;
91  						a5 = a5 + account[i];
92  					}
93  				} else {
94  					if (c2 == 0 && d2 == 0) {
95  						c2 = 1;
96  						a5 = a5 + account[i];
97  					} else {
98  						c2 = 0;
99  						a5 = a5 + account[i];
100 					}
101 				}
102 			} else {
103 				if (account[i] > 5) {
104 					if (c2 == 0) {
105 						c2 = 1;
106 						d2 = 0;
107 						a5 = a5 - 6 + (account[i] - 6);
108 					} else {
109 						c2 = 0;
110 						d2 = 1;
111 						a5 = a5 - account[i];
112 					}
113 				} else {
114 					if (c2 == 0) {
115 						c2 = 1;
116 						a5 = a5 - account[i];
117 					} else {
118 						c2 = 0;
119 						a5 = a5 - account[i];
120 					}
121 				}
122 			}
123 			++i;
124 		}
125 		while (a5 < 0 || a5 > 4) {
126 			if (a5 > 4) {
127 				a5 = a5 - 5;
128 			} else {
129 				a5 = a5 + 5;
130 			}
131 		}
132 		if (d2 == 0) {
133 			cd = tabOneMethodA[a5];
134 		} else {
135 			cd = tabTwoMethodA[a5];
136 		}
137 		if (cd != account[9]) {
138 			if (account[4] == 0) {
139 				if (cd > 4) {
140 					cd = cd - 5;
141 				} else {
142 					cd = cd + 5;
143 				}
144 			}
145 		}
146 
147 		return new CheckDigit(9, cd);
148 	}
149 
150 	private CheckDigit calculateMethodB(final AccountCode accountCode) {
151 
152 		return new Strategy33().calculateCheckDigit(null, accountCode);
153 
154 	}
155 
156 	private CheckDigit calculateMethodC(final AccountCode accountCode) {
157 
158 		int sum = 0;
159 
160 		for (int i = AccountCode.ACCOUNT_CODE_MAX_LENGTH - 2; i >= 4; --i) {
161 			sum += accountCode.getDigitAtPos(i) * multiplicatorsMethodC[i];
162 		}
163 
164 		int mod = sum % 7;
165 		int cd = mod == 0 ? 0 : 7 - mod;
166 
167 		return new CheckDigit(9, cd);
168 	}
169 
170 }