HashStream.st
author Stefan Vogel <sv@exept.de>
Wed, 09 Nov 2005 16:56:10 +0100
changeset 8979 869510c58b9c
parent 7251 0ef2a2a16faa
child 11799 2cbd0a5e7c64
child 17711 39faaaf888b4
permissions -rw-r--r--
Move #isFinite and #isInfinite from Number to ArithmethicValue

"
 COPYRIGHT (c) 1999 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"


"{ Package: 'stx:libbasic' }"

Stream subclass:#HashStream
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'System-Crypt-Streams'
!

!HashStream class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1999 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

!

documentation
"
    Abstract class. Subclasses generate hash values used as checksums
    or for generating cryptographic signatures.

    [author:]
        Stefan Vogel

    [see also:]
        SHA1Stream MD5Stream
"
! !

!HashStream class methodsFor:'instance creation'!

new
    "have to re-allow new - it was disabled in Stream"
    ^ self basicNew initialize


!

random
    "create a random number generator using myself"

    ^ HashRandom with:self

    "
     SHA1Stream random next
    "

    "Modified: / 12.11.1999 / 17:21:17 / stefan"
! !

!HashStream class methodsFor:'testing'!

test
    "test against testVector"

    self testVector do:[:pair |
        |data expectedHash hashStream|

        data := pair first.
        expectedHash := pair second.

        hashStream := self new.
        hashStream nextPut:data.
        hashStream hashValue ~= expectedHash ifTrue:[
            self error:'Test failed'
        ].
        (self hashValueOf:data) ~= expectedHash ifTrue:[
            self error:'Test failed'
        ].
    ].

    "
        MD5Stream test.
        SHA1Stream test.
        RipeMD160Stream test.
    "
!

testVector
    "define a testvector to test the implementation"

    ^ self subclassResponsibility
! !

!HashStream class methodsFor:'utilities'!

hashValueOf:aStringOrByteArrayOrStream
    |hashStream|

    hashStream := self new.
    aStringOrByteArrayOrStream readStream copyToEndInto:hashStream.

    ^ hashStream hashValue

    "
     MD5Stream hashValueOf:'BlaBlaBla'
     MD5Stream hashValueOf:('Makefile' asFilename readStream)
     MD5Stream hashValueOf:('BlaBlaBla' readStream)
    "
!

hashValueOfFile:aFilename
    |stream hash|

    [
        stream := aFilename asFilename readStream.
        stream binary.
        hash := self hashValueOf:stream.
    ] ensure:[
        stream notNil ifTrue:[
            stream close
        ].
    ].
    ^ hash.

    "
     MD5Stream hashValueOfFile:'Makefile'
    "
! !

!HashStream methodsFor:'accessing'!

contents
    "return the entire contents of the stream
     - this is our hashValue."

    ^ self hashValue

    "Created: / 17.3.1999 / 15:10:03 / stefan"
! !

!HashStream methodsFor:'not implemented'!

next
    ^ self shouldNotImplement

    "Created: / 17.3.1999 / 15:11:03 / stefan"
! !

!HashStream methodsFor:'queries'!

blockSize
    "the class knows about the basic block size"

    ^ self class blockSize

    "Created: / 18.3.1999 / 10:17:02 / stefan"
!

hashSize
    "the class knows about the basic hash size"

    ^ self class hashSize

    "Created: / 18.3.1999 / 10:17:12 / stefan"
    "Modified: / 15.10.1999 / 11:53:20 / stefan"
!

hashValue
    "retunr the value of the computeted hash"

    ^ self subclassResponsibility
!

isReadable
    "return true, if reading is supported by the recevier.
     Always return false here"

    ^ false

    "Modified: / 17.3.1999 / 15:06:09 / stefan"
!

isWritable
    "return true, if writing is supported by the recevier.
     Always return true here"

    ^ true

    "Created: / 17.3.1999 / 15:05:49 / stefan"
! !

!HashStream methodsFor:'testing'!

atEnd
    "return true if the end of the stream has been reached;
    this is never reached"

    ^ false

    "Created: / 17.3.1999 / 15:08:55 / stefan"
! !

!HashStream methodsFor:'writing'!

nextPut:anObject
    "add the hash of anObject to the computed hash so far.
     anObject can be a Character, SmallInteger, or Character-, Byte-
     Integer-Array"

    ^ self subclassResponsibility
!

nextPutAll:aCollection
    "Hash streams handle Strings and ByteArrays in nextPut:"

    aCollection class isBytes ifTrue:[
        self nextPut:aCollection.
    ] ifFalse:[
        super nextPutAll:aCollection
    ].

    "Created: / 14.10.1999 / 11:22:50 / stefan"
!

nextPutBytes:count from:anObject startingAt:start
    "write count bytes from an object starting at index start.
     Return the number of bytes written.
     The object must have non-pointer indexed instvars 
     (i.e. be a ByteArray, String, Float- or DoubleArray).     
     Use with care - non object oriented i/o.
     This is provided for compatibility with externalStream;
     to support binary storage.

     Redefined, because HashStream encodes integers as 4 bytes.
     You should implement this method in subclasses"

    |idx|

    "self subclassResponsibility"

    idx := start.
    1 to:count do:[:i |
        self nextPut:(anObject byteAt:idx) asCharacter.
        idx := idx + 1
    ].
    ^ count
! !

!HashStream class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libbasic/HashStream.st,v 1.5 2003-05-05 12:58:46 stefan Exp $'
! !