on 2012 May 01 2:31 PM
This has been a long-term annoyance for me and I would very much like to know if I'm working too hard. It appears as though the hash functions in ASA (mostly HASH and BASE64_*) accept varbinary parameters but return hex strings as their result. This gets really annoying when trying to use the results of a HASH (for instance, the next step after calling HASH is normally to BASE64-encode the result) and the only function ASA seems to provide to translate from one to the other is HEX2INT. As one example, I just finished writing a HMAC function and I ran into this at least a couple of times (very grateful that XOR handles varbinary though).
I ended up writing a function that would take the results of these functions and translate it back into a varbinary using HEX2INT byte-by-byte, but this is starting to feel rediculously over-complicated. I'd rather not write my own DLL plugin to do this stuff (reimplementing crypto without a doctorate is usually a really bad idea) but is there something obvious that I'm not seeing here?
Try defining:
create function hextobin( in @hex long varchar ) returns long binary begin declare @bin long binary; if patindex( '%[^0-9a-fA-F]%', @hex ) = 0 then -- check for invalid hex string execute immediate( 'set @bin = cast( 0x' || @hex || ' as long binary )' ); end if; return @bin; end;
and then just use hextobin as you would normally.
HTH
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
That's... slightly better than my WHILE loop repeatedly calling HEXTOINT. I'm not sure what the tradeoff is between execute immediate vs trying to have asa do string operations. Am i right that this workaround is necessary and there is no facility that handles hex strings of arbitrary lengths nor one to prevent them from being generated?
I think the above is the best you can do for now. See my other comment for the future. i.e. in the future you will not need to define hextobin() since it will be natively supported as a built-in function.
Re. which is better: execute immediate or a big loop that manipulates strings, the answer is that execute immediate will run much faster than a loop.
No, but I managed to find a database that was native-rebuilt under ASA12 so that I could unload a DLL that I had used under a different database on the same engine. I'm tempted to explicitly define it so I can use it in more places without having to rebuild though.
Functions like HEXTOBIN would likely be more of a reserved keyword though, I'd be curious as to how an engine implementing that as a keyword would handle a validly-rebuilt database with a function defining the same term.
Well, for collisions with newly introduced reserved words, the rebuild will usually fail - cited from the v12.0.1 docs:
If an object name (such as a table, column, variable, or parameter name) corresponds to a reserved word introduced in a later version of SQL Anywhere (such as NCHAR), then the reload fails. [...]
Change all references to the reserved word to use a different name. For variable names, prefixing the name with @ is a common convention that prevents naming conflicts.
Howver, the names of builtin functions usually aren't reserved words, so I'm not sure whether a rebuild would fail when they get non-unique...
If you wish to avoid EXECUTE IMMEDIATE, you can also (ab)use the openstring algorithm to load any string in LOAD table format:
create or replace function hextobin( in @hex long varchar ) returns long binary begin declare @bin long binary; if locate(@hex,'0x') <> 1 then set @hex='0x'||@hex; end if; select bin into @bin from openstring( value @hex ) with( bin long binary ) B; return @bin; end go select 0x616263, hextobin( '616263'), hextobin( '0x616263');
The algorithm validates the string.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
71 | |
11 | |
10 | |
10 | |
10 | |
8 | |
7 | |
7 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.