blob: 6bfc2b27d7637514068ea212a0cd3921440a278f [file] [log] [blame]
/*****************************************************************************
# *
# Copyright 2019 AT&T Intellectual Property *
# *
# Licensed under the Apache License, Version 2.0 (the "License"); *
# you may not use this file except in compliance with the License. *
# You may obtain a copy of the License at *
# *
# http://www.apache.org/licenses/LICENSE-2.0 *
# *
# Unless required by applicable law or agreed to in writing, software *
# distributed under the License is distributed on an "AS IS" BASIS, *
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
# See the License for the specific language governing permissions and *
# limitations under the License. *
# *
******************************************************************************/
/*
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
* All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
#include <asn_random_fill.h>
#include <constr_TYPE.h>
int
asn_random_fill(const struct asn_TYPE_descriptor_s *td, void **struct_ptr,
size_t length) {
if(td && td->op->random_fill) {
asn_random_fill_result_t res =
td->op->random_fill(td, struct_ptr, 0, length);
return (res.code == ARFILL_OK) ? 0 : -1;
} else {
return -1;
}
}
static uintmax_t
asn__intmax_range(intmax_t lb, intmax_t ub) {
assert(lb <= ub);
if((ub < 0) == (lb < 0)) {
return ub - lb;
} else if(lb < 0) {
return 1 + ((uintmax_t)ub + (uintmax_t)-(lb + 1));
} else {
assert(!"Unreachable");
return 0;
}
}
intmax_t
asn_random_between(intmax_t lb, intmax_t rb) {
if(lb == rb) {
return lb;
} else {
const uintmax_t intmax_max = ((~(uintmax_t)0) >> 1);
uintmax_t range = asn__intmax_range(lb, rb);
uintmax_t value = 0;
uintmax_t got_entropy = 0;
assert(RAND_MAX > 0xffffff); /* Seen 7ffffffd! */
assert(range < intmax_max);
for(; got_entropy < range;) {
got_entropy = (got_entropy << 24) | 0xffffff;
value = (value << 24) | (random() % 0xffffff);
}
return lb + (intmax_t)(value % (range + 1));
}
}