added single(); update README

pull/1/head
Avril 4 years ago
parent eefb716ac2
commit 4ed44555f3
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -73,12 +73,14 @@
khash_context ctx; khash_context ctx;
assert(khash_new_context(KHASH_ALGO_SHA256, KHASH_SALT_TYPE_SPECIFIC, input_salt, strlen(input_salt), &ctx) == KHASH_SUCCESS, "khash_new_context() failed."); assert(khash_new_context(KHASH_ALGO_SHA256, KHASH_SALT_TYPE_SPECIFIC, input_salt, strlen(input_salt), &ctx) == KHASH_SUCCESS, "khash_new_context() failed.");
#+END_SRC #+END_SRC
Find the buffer length we need. Find the buffer length we need and allocate a buffer.
#+BEGIN_SRC c #+BEGIN_SRC c
size_t length; size_t length;
assert(khash_length(&ctx, input_data, strlen(input_data), &length) == KHASH_SUCCESS, "khash_length() failed."); assert(khash_length(&ctx, input_data, strlen(input_data), &length) == KHASH_SUCCESS, "khash_length() failed.");
#+END_SRC #+END_SRC
Create the buffer and hash, then print the result to ~stdout~. Create the buffer and hash, then print the result to ~stdout~.
#+BEGIN_SRC c #+BEGIN_SRC c
char* buffer = alloca(length+1); char* buffer = alloca(length+1);
@ -89,6 +91,14 @@
printf("Kana hash: %s\n", buffer); printf("Kana hash: %s\n", buffer);
#+END_SRC #+END_SRC
Alternatively, we can allocate the max length needed instead of calculating it.
#+BEGIN_SRC c
size_t length;
assert(khash_max_length(KHASH_ALGO_SHA256, strlen(input_data), &length) == KHASH_SUCCESS, "khash_max_length() failed.");
char* buffer = alloca(length+1);
memset(buffer, 0, length+1); //Ensure NUL terminators.
#+END_SRC
*** Definitions *** Definitions
**** Macros **** Macros
@ -187,6 +197,14 @@
const new_ctx = ctx.clone(); const new_ctx = ctx.clone();
#+END_SRC #+END_SRC
**** Alternatively
To create a hash in one line you can do one of the following.
#+BEGIN_SRC javascript
const hash1 = new Kana(Kana.ALGO_DEFAULT, new Salt("salt~")).once("input string~"); //Allocates the exact space required for the output string.
const hash2 = Kana.single(Kana.ALGO_DEFAULT, new Salt("salt~")).once("input string~"); //Allocates the max space required for the output string, instead of the exact. Might be faster.
#+END_SRC
*** Interface documentation *** Interface documentation
The 2 exported objects are ~Kana~ and ~Salt~. The 2 exported objects are ~Kana~ and ~Salt~.
~Kana~'s constructor expects between 0 and 2 arguments. ~Kana~'s constructor expects between 0 and 2 arguments.
@ -194,6 +212,7 @@
+ The second is either an instance of ~Salt~ or empty, if empty ~Kana~ uses the default library salt. + The second is either an instance of ~Salt~ or empty, if empty ~Kana~ uses the default library salt.
~Salt~'s constructor expects 0 or 1 argument. ~Salt~'s constructor expects 0 or 1 argument.
+ Either a string to use as the specific salt or empty, if empty there is no salt. + Either a string to use as the specific salt or empty, if empty there is no salt.
~Kana~ also has a static function ~single(algo, salt, input)~ which automatically creates a context, computes the hash, frees the context, and then returns the computed hash as a JavaScript string.
**** Defined constants **** Defined constants
| Name | Type | Description | | Name | Type | Description |

@ -11,6 +11,7 @@ const PSalt = ref.refType(Salt);
const Context = struct({ const Context = struct({
'algo': 'char', 'algo': 'char',
'flags': 'long',
'salt': Salt, 'salt': Salt,
}); });
const PContext = ref.refType(Context); const PContext = ref.refType(Context);
@ -23,6 +24,7 @@ const lib = ffi.Library('libkhash', {
'khash_length': ['int', [PContext, 'string', 'long', PLong]], 'khash_length': ['int', [PContext, 'string', 'long', PLong]],
'khash_do': ['int', [PContext, 'string', 'long', 'string', 'long']], 'khash_do': ['int', [PContext, 'string', 'long', 'string', 'long']],
'khash_max_length': ['int', ['char', 'long', PLong]],
}); });
const ctx_create = (algo, salt, salt_ref, salt_sz) => { const ctx_create = (algo, salt, salt_ref, salt_sz) => {
@ -51,6 +53,11 @@ const khash_do = (ctx, jsstring, len) => {
lib.khash_do(ctx,string,string.length,buffer,len); lib.khash_do(ctx,string,string.length,buffer,len);
return ref.readCString(buffer,0); return ref.readCString(buffer,0);
}; };
const khash_max_length = (algo, input) => {
let len = ref.alloc('long');
lib.khash_max_length(algo, input, len);
return len.deref();
};
const get_salt_type = (salt) => { const get_salt_type = (salt) => {
if (salt && salt.tag) { if (salt && salt.tag) {
@ -83,6 +90,15 @@ function Kana(algo, salt)
this.ctx = ctx_create(algo || 0, stype, fbuffer, fbuffer ? fbuffer.length : 0); this.ctx = ctx_create(algo || 0, stype, fbuffer, fbuffer ? fbuffer.length : 0);
} }
} }
Kana.single = function(algo, salt, input) {
const mlen = khash_max_length(algo || 0, input.length);
const stype = get_salt_type(salt);
const fbuffer = salt ? salt.buffer || null : null;
const ctx = ctx_create(algo || 0, stype, fbuffer, fbuffer ? fbuffer.length : 0);
return khash_do(ctx, input, mlen);
};
const K = Kana.prototype; const K = Kana.prototype;
/// Free the associated context. /// Free the associated context.

@ -0,0 +1,5 @@
const kana = require('./kana');
console.log(new kana(null, null).once("hello loli"));
console.log(kana.single(kana.ALGO_DEFAULT, null, "hello loli"));
Loading…
Cancel
Save