2008-07-14 01:15:55 +04:00
/* large.c - Handles binary manipulation of large numbers */
/*
libzint - the open source barcode library
2017-08-07 10:37:02 +03:00
Copyright ( C ) 2008 - 2017 Robin Stuart < rstuart114 @ gmail . com >
2008-07-14 01:15:55 +04:00
2013-05-16 21:26:38 +04:00
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions
are met :
2008-07-14 01:15:55 +04:00
2017-10-23 22:37:52 +03:00
1. Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
2013-05-16 21:26:38 +04:00
2. Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in the
2017-10-23 22:37:52 +03:00
documentation and / or other materials provided with the distribution .
2013-05-16 21:26:38 +04:00
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
2017-10-23 22:37:52 +03:00
without specific prior written permission .
2008-07-14 01:15:55 +04:00
2013-05-16 21:26:38 +04:00
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS " AND
ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT
LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY
2017-10-23 22:37:52 +03:00
OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
2013-05-16 21:26:38 +04:00
SUCH DAMAGE .
2016-02-20 13:50:15 +03:00
*/
2008-07-14 01:15:55 +04:00
# include <stdio.h>
# include <string.h>
2009-06-03 00:23:38 +04:00
# include "common.h"
# include "large.h"
2008-07-14 01:15:55 +04:00
2016-02-20 13:50:15 +03:00
void binary_add ( short int accumulator [ ] , short int input_buffer [ ] ) { /* Binary addition */
2017-09-10 18:03:09 +03:00
int i , carry ;
2016-02-20 13:50:15 +03:00
carry = 0 ;
for ( i = 0 ; i < 112 ; i + + ) {
2017-09-10 18:03:09 +03:00
int done = 0 ;
2017-10-23 22:37:52 +03:00
if ( ( ( input_buffer [ i ] = = 0 ) & & ( accumulator [ i ] = = 0 ) )
2016-02-20 13:50:15 +03:00
& & ( ( carry = = 0 ) & & ( done = = 0 ) ) ) {
accumulator [ i ] = 0 ;
carry = 0 ;
done = 1 ;
}
2017-10-23 22:37:52 +03:00
if ( ( ( input_buffer [ i ] = = 0 ) & & ( accumulator [ i ] = = 0 ) )
2016-02-20 13:50:15 +03:00
& & ( ( carry = = 1 ) & & ( done = = 0 ) ) ) {
accumulator [ i ] = 1 ;
carry = 0 ;
done = 1 ;
}
2017-10-23 22:37:52 +03:00
if ( ( ( input_buffer [ i ] = = 0 ) & & ( accumulator [ i ] = = 1 ) )
2016-02-20 13:50:15 +03:00
& & ( ( carry = = 0 ) & & ( done = = 0 ) ) ) {
accumulator [ i ] = 1 ;
carry = 0 ;
done = 1 ;
}
2017-10-23 22:37:52 +03:00
if ( ( ( input_buffer [ i ] = = 0 ) & & ( accumulator [ i ] = = 1 ) )
2016-02-20 13:50:15 +03:00
& & ( ( carry = = 1 ) & & ( done = = 0 ) ) ) {
accumulator [ i ] = 0 ;
carry = 1 ;
done = 1 ;
}
2017-10-23 22:37:52 +03:00
if ( ( ( input_buffer [ i ] = = 1 ) & & ( accumulator [ i ] = = 0 ) )
2016-02-20 13:50:15 +03:00
& & ( ( carry = = 0 ) & & ( done = = 0 ) ) ) {
accumulator [ i ] = 1 ;
carry = 0 ;
done = 1 ;
}
2017-10-23 22:37:52 +03:00
if ( ( ( input_buffer [ i ] = = 1 ) & & ( accumulator [ i ] = = 0 ) )
2016-02-20 13:50:15 +03:00
& & ( ( carry = = 1 ) & & ( done = = 0 ) ) ) {
accumulator [ i ] = 0 ;
carry = 1 ;
done = 1 ;
}
2017-10-23 22:37:52 +03:00
if ( ( ( input_buffer [ i ] = = 1 ) & & ( accumulator [ i ] = = 1 ) )
2016-02-20 13:50:15 +03:00
& & ( ( carry = = 0 ) & & ( done = = 0 ) ) ) {
accumulator [ i ] = 0 ;
carry = 1 ;
done = 1 ;
}
2017-10-23 22:37:52 +03:00
if ( ( ( input_buffer [ i ] = = 1 ) & & ( accumulator [ i ] = = 1 ) )
2016-02-20 13:50:15 +03:00
& & ( ( carry = = 1 ) & & ( done = = 0 ) ) ) {
accumulator [ i ] = 1 ;
carry = 1 ;
done = 1 ;
}
}
2008-07-14 01:15:55 +04:00
}
2017-10-23 22:37:52 +03:00
void binary_subtract ( short int accumulator [ ] , short int input_buffer [ ] ) {
2016-02-20 13:50:15 +03:00
/* 2's compliment subtraction */
/* take input_buffer from accumulator and put answer in accumulator */
int i ;
short int sub_buffer [ 112 ] ;
for ( i = 0 ; i < 112 ; i + + ) {
if ( input_buffer [ i ] = = 0 ) {
sub_buffer [ i ] = 1 ;
} else {
sub_buffer [ i ] = 0 ;
}
}
binary_add ( accumulator , sub_buffer ) ;
sub_buffer [ 0 ] = 1 ;
for ( i = 1 ; i < 112 ; i + + ) {
sub_buffer [ i ] = 0 ;
}
binary_add ( accumulator , sub_buffer ) ;
2008-07-14 01:15:55 +04:00
}
2018-02-11 11:00:32 +03:00
void binary_multiply ( short int reg [ ] , char data [ ] ) {
/* Multiply the contents of reg[] by a number */
short int temp [ 112 ] = { 0 } ;
short int accum [ 112 ] = { 0 } ;
int i ;
binary_load ( temp , data , strlen ( data ) ) ;
for ( i = 0 ; i < 102 ; i + + ) {
if ( temp [ i ] = = 1 ) {
binary_add ( accum , reg ) ;
}
shiftup ( reg ) ;
}
for ( i = 0 ; i < 112 ; i + + ) {
reg [ i ] = accum [ i ] ;
}
}
2016-02-20 13:50:15 +03:00
void shiftdown ( short int buffer [ ] ) {
int i ;
2012-12-31 17:41:59 +04:00
2016-02-20 13:50:15 +03:00
buffer [ 102 ] = 0 ;
buffer [ 103 ] = 0 ;
2008-07-14 01:15:55 +04:00
2016-02-20 13:50:15 +03:00
for ( i = 0 ; i < 102 ; i + + ) {
buffer [ i ] = buffer [ i + 1 ] ;
}
2008-07-14 01:15:55 +04:00
}
2016-02-20 13:50:15 +03:00
void shiftup ( short int buffer [ ] ) {
int i ;
2012-12-31 17:41:59 +04:00
2016-02-20 13:50:15 +03:00
for ( i = 102 ; i > 0 ; i - - ) {
buffer [ i ] = buffer [ i - 1 ] ;
}
2012-12-31 17:41:59 +04:00
2016-02-20 13:50:15 +03:00
buffer [ 0 ] = 0 ;
2008-07-14 01:15:55 +04:00
}
2016-02-20 13:50:15 +03:00
short int islarger ( short int accum [ ] , short int reg [ ] ) {
/* Returns 1 if accum[] is larger than reg[], else 0 */
int i , latch , larger ;
latch = 0 ;
i = 103 ;
larger = 0 ;
do {
if ( ( accum [ i ] = = 1 ) & & ( reg [ i ] = = 0 ) ) {
latch = 1 ;
larger = 1 ;
}
if ( ( accum [ i ] = = 0 ) & & ( reg [ i ] = = 1 ) ) {
latch = 1 ;
}
i - - ;
2019-09-01 22:23:15 +03:00
} while ( ( latch = = 0 ) & & ( i > = 0 ) ) ;
2016-02-20 13:50:15 +03:00
return larger ;
2008-07-14 01:15:55 +04:00
}
2017-05-29 12:43:47 +03:00
void binary_load ( short int reg [ ] , char data [ ] , const size_t src_len ) {
2017-06-13 22:05:35 +03:00
size_t read ;
int i ;
2016-02-20 13:50:15 +03:00
short int temp [ 112 ] = { 0 } ;
2012-12-31 17:41:59 +04:00
2016-02-20 13:50:15 +03:00
for ( i = 0 ; i < 112 ; i + + ) {
reg [ i ] = 0 ;
}
2012-12-31 17:41:59 +04:00
2016-02-20 13:50:15 +03:00
for ( read = 0 ; read < src_len ; read + + ) {
2008-07-14 01:15:55 +04:00
2016-02-20 13:50:15 +03:00
for ( i = 0 ; i < 112 ; i + + ) {
temp [ i ] = reg [ i ] ;
}
2012-12-31 17:41:59 +04:00
2016-02-20 13:50:15 +03:00
for ( i = 0 ; i < 9 ; i + + ) {
binary_add ( reg , temp ) ;
}
2012-12-31 17:41:59 +04:00
2017-08-07 10:37:02 +03:00
for ( i = 0 ; i < 112 ; i + + ) {
2016-02-20 13:50:15 +03:00
temp [ i ] = 0 ;
}
2017-10-23 22:37:52 +03:00
2017-08-07 10:37:02 +03:00
for ( i = 0 ; i < 4 ; i + + ) {
if ( ctoi ( data [ read ] ) & ( 0x01 < < i ) ) temp [ i ] = 1 ;
}
2012-12-31 17:41:59 +04:00
2016-02-20 13:50:15 +03:00
binary_add ( reg , temp ) ;
}
2008-07-14 01:15:55 +04:00
}
2017-10-23 22:37:52 +03:00