| 1773 | |
| 1774 | == Bash == |
| 1775 | {{{ |
| 1776 | #!/bin/bash |
| 1777 | |
| 1778 | # Copyright (C) |
| 1779 | # 2014 - Tomasz Wisniewski dagon666 |
| 1780 | # This program is free software; you can redistribute it and/or |
| 1781 | # modify it under the terms of the GNU General Public License |
| 1782 | # as published by the Free Software Foundation; either version 2 |
| 1783 | # of the License, or (at your option) any later version. |
| 1784 | # |
| 1785 | # This program is distributed in the hope that it will be useful, |
| 1786 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 1787 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 1788 | # GNU General Public License for more details. |
| 1789 | # |
| 1790 | # You should have received a copy of the GNU General Public License |
| 1791 | # along with this program; if not, write to the Free Software |
| 1792 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 1793 | |
| 1794 | |
| 1795 | correct_64bit() { |
| 1796 | local pow32=$(( 1 << 32 )) |
| 1797 | |
| 1798 | while [ "$g_lo" -ge $pow32 ]; do |
| 1799 | g_lo=$(( g_lo - pow32 )) |
| 1800 | g_hi=$(( g_hi + 1 )) |
| 1801 | done |
| 1802 | while [ "$g_hi" -ge $pow32 ]; do |
| 1803 | g_hi=$(( g_hi - pow32 )) |
| 1804 | done |
| 1805 | } |
| 1806 | |
| 1807 | |
| 1808 | hash_part() { |
| 1809 | local file="$1" |
| 1810 | local curr=0 |
| 1811 | local dsize=$((8192*8)) |
| 1812 | |
| 1813 | local bytes_at_once=2048 |
| 1814 | local groups=$(( (bytes_at_once / 8) - 1 )) |
| 1815 | local k=0 |
| 1816 | local i=0 |
| 1817 | local offset=0 |
| 1818 | declare -a num=() |
| 1819 | |
| 1820 | while [ "$curr" -lt "$dsize" ]; do |
| 1821 | num=( $(od -t u1 -An -N "$bytes_at_once" -w$bytes_at_once -j "$curr" "$file") ) |
| 1822 | |
| 1823 | for k in $(seq 0 $groups); do |
| 1824 | |
| 1825 | offset=$(( k * 8 )) |
| 1826 | |
| 1827 | g_lo=$(( g_lo + \ |
| 1828 | num[$(( offset + 0 ))] + \ |
| 1829 | (num[$(( offset + 1 ))] << 8) + \ |
| 1830 | (num[$(( offset + 2 ))] << 16) + \ |
| 1831 | (num[$(( offset + 3 ))] << 24) )) |
| 1832 | |
| 1833 | g_hi=$(( g_hi + \ |
| 1834 | num[$(( offset + 4 ))] + \ |
| 1835 | (num[$(( offset + 5 ))] << 8) + \ |
| 1836 | (num[$(( offset + 6 ))] << 16) + \ |
| 1837 | (num[$(( offset + 7 ))] << 24) )) |
| 1838 | |
| 1839 | correct_64bit |
| 1840 | done |
| 1841 | |
| 1842 | curr=$(( curr + bytes_at_once )) |
| 1843 | done |
| 1844 | } |
| 1845 | |
| 1846 | |
| 1847 | hash_file() { |
| 1848 | g_lo=0 |
| 1849 | g_hi=0 |
| 1850 | |
| 1851 | local file="$1" |
| 1852 | local size=$(stat -c%s "$file") |
| 1853 | local offset=$(( size - 65536 )) |
| 1854 | |
| 1855 | local part1=$(mktemp part1.XXXXXXXX) |
| 1856 | local part2=$(mktemp part2.XXXXXXXX) |
| 1857 | |
| 1858 | dd if="$file" bs=8192 count=8 of="$part1" 2> /dev/null |
| 1859 | dd if="$file" skip="$offset" bs=1 of="$part2" 2> /dev/null |
| 1860 | |
| 1861 | hash_part "$part1" |
| 1862 | hash_part "$part2" |
| 1863 | |
| 1864 | g_lo=$(( g_lo + size )) |
| 1865 | correct_64bit |
| 1866 | |
| 1867 | unlink "$part1" |
| 1868 | unlink "$part2" |
| 1869 | |
| 1870 | printf "%08x%08x\n" $g_hi $g_lo |
| 1871 | } |
| 1872 | |
| 1873 | hash_file "breakdance.avi" |
| 1874 | echo "8e245d9679d31e12 <- should be" |
| 1875 | |
| 1876 | hash_file "dummy.bin" |
| 1877 | echo "61f7751fc2a72bfb <- should be" |
| 1878 | }}} |