Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: blinky_max32630fthr
randLIB.c
00001 /* 00002 * Copyright (c) 2014-2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include <stdint.h> 00017 #include <stdlib.h> 00018 #include <sys/types.h> 00019 #include <sys/stat.h> 00020 #include <fcntl.h> 00021 #include <unistd.h> 00022 #include "randLIB.h" 00023 00024 /** 00025 * \brief Init seed for Pseudo Random. 00026 * On a Linux, this does nothing. 00027 * 00028 * \return None 00029 * 00030 */ 00031 void randLIB_seed_random(void) 00032 { 00033 } 00034 00035 /** 00036 * \brief Generate 8-bit random number. 00037 * 00038 * \param None 00039 * \return 8-bit random number 00040 * 00041 */ 00042 uint8_t randLIB_get_8bit(void) 00043 { 00044 uint8_t ret_val; 00045 randLIB_get_n_bytes_random(&ret_val, 1); 00046 return ret_val; 00047 } 00048 00049 /** 00050 * \brief Generate 16-bit random number. 00051 * 00052 * \param None 00053 * \return 16-bit random number 00054 * 00055 */ 00056 uint16_t randLIB_get_16bit(void) 00057 { 00058 uint16_t ret_val; 00059 00060 randLIB_get_n_bytes_random((uint8_t*)&ret_val, 2); 00061 return ret_val; 00062 } 00063 /** 00064 * \brief Generate 32-bit random number. 00065 * 00066 * \param None 00067 * \return 32-bit random number 00068 * 00069 */ 00070 uint32_t randLIB_get_32bit(void) 00071 { 00072 uint32_t ret_val; 00073 randLIB_get_n_bytes_random((uint8_t*)&ret_val, 4); 00074 return ret_val; 00075 } 00076 00077 00078 /** 00079 * \brief Generate n-bytes random numbers. 00080 * 00081 * \param data_ptr pointer where random will be stored 00082 * \param eight_bit_boundary how many bytes need random 00083 * \return 0 process valid 00084 * \return -1 Unsupported Parameters or failed to get random data. 00085 * 00086 */ 00087 int8_t randLIB_get_n_bytes_random(uint8_t *data_ptr, uint8_t eight_bit_boundary) 00088 { 00089 if ((data_ptr == 0) || (eight_bit_boundary == 0)) { 00090 return -1; 00091 } 00092 00093 int fd = open("/dev/urandom", O_RDONLY); 00094 if (fd != -1) { 00095 size_t len = read(fd, data_ptr, eight_bit_boundary); 00096 close(fd); 00097 if (len == eight_bit_boundary) 00098 return 0; 00099 } 00100 00101 return -1; 00102 } 00103 00104 /** 00105 * \brief Generate a random number within a range. 00106 * 00107 * The result is linearly distributed in the range [min..max], inclusive. 00108 * 00109 * \param min minimum value that can be generated 00110 * \param max maximum value that can be generated 00111 */ 00112 uint16_t randLIB_get_random_in_range(uint16_t min, uint16_t max) 00113 { 00114 /* This special case is potentially common, particularly in this routine's 00115 * first user (Trickle), so worth catching immediately */ 00116 if (min == max) { 00117 return min; 00118 } 00119 00120 /* 16-bit arithmetic below fails in this extreme case; we can optimise it */ 00121 if (max - min == 0xFFFF) { 00122 return randLIB_get_16bit(); 00123 } 00124 00125 unsigned int values_needed = max + 1 - min; 00126 unsigned int band_size = 0x10000u / values_needed; 00127 unsigned int top_of_bands = band_size * values_needed; 00128 unsigned int result; 00129 do { 00130 result = randLIB_get_16bit(); 00131 } while (result >= top_of_bands); 00132 00133 return min + (uint16_t)(result / band_size); 00134 } 00135 00136 /** 00137 * \brief Randomise a base 32-bit number by a jitter factor 00138 * 00139 * The result is linearly distributed in the jitter range, which is expressed 00140 * as fixed-point unsigned 1.15 values. For example, to produce a number in the 00141 * range [0.75 * base, 1.25 * base], set min_factor to 0x6000 and max_factor to 00142 * 0xA000. 00143 * 00144 * Result is clamped to 0xFFFFFFFF if it overflows. 00145 * 00146 * \param base The base 32-bit value 00147 * \param min_factor The minimum value for the random factor 00148 * \param max_factor The maximum value for the random factor 00149 */ 00150 uint32_t randLIB_randomise_base(uint32_t base, uint16_t min_factor, uint16_t max_factor) 00151 { 00152 uint16_t random_factor = randLIB_get_random_in_range(min_factor, max_factor); 00153 00154 /* 32x16-bit long multiplication, to get 48-bit result */ 00155 uint32_t hi = (base >> 16) * random_factor; 00156 uint32_t lo = (base & 0xFFFF) * random_factor; 00157 /* Add halves, and take top 32 bits of 48-bit result */ 00158 uint32_t res = hi + (lo >> 16); 00159 00160 /* Randomisation factor is *2^15, so need to shift up 1 more bit, avoiding overflow */ 00161 if (res & 0x80000000) { 00162 res = 0xFFFFFFFF; 00163 } else { 00164 res = (res << 1) | ((lo >> 15) & 1); 00165 } 00166 00167 return res; 00168 }
Generated on Tue Jul 12 2022 14:21:18 by
 1.7.2
 1.7.2